UNPKG

scichart

Version:

Fast WebGL JavaScript Charting Library and Framework

824 lines 50.4 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.SciChartRenderer = void 0; var app_1 = require("../../constants/app"); var Rect_1 = require("../../Core/Rect"); var AutoRange_1 = require("../../types/AutoRange"); var DefaultRenderLayer_1 = require("../../types/DefaultRenderLayer"); var WebGlRenderContext2D_1 = require("../Drawing/WebGlRenderContext2D"); var SciChartSurface_1 = require("../Visuals/SciChartSurface"); var SciChartSurfaceBase_1 = require("../Visuals/SciChartSurfaceBase"); var DpiHelper_1 = require("../Visuals/TextureManager/DpiHelper"); var RenderPassData_1 = require("./RenderPassData"); var RenderPassInfo_1 = require("./RenderPassInfo"); var NativeObject_1 = require("../Visuals/Helpers/NativeObject"); var createNativeRect_1 = require("../Visuals/Helpers/createNativeRect"); var parseColor_1 = require("../../utils/parseColor"); var logger_1 = require("../../utils/logger"); var performance_1 = require("../../utils/performance"); var ExtremeResamplerHelper_1 = require("../Numerics/Resamplers/ExtremeResamplerHelper"); var ModifierType_1 = require("../../types/ModifierType"); var translate_1 = require("../../utils/translate"); var watermarkHelpers_1 = require("../../utils/watermarkHelpers"); var Thickness_1 = require("../../Core/Thickness"); var OrderedRenderable_1 = require("../../types/OrderedRenderable"); /** * A class used internally in SciChart to perform layout, arrangement, data-preparation and rendering on the Cartesian 2D {@link SciChartSurface} */ var SciChartRenderer = /** @class */ (function () { /** * Creates an instance of the SciChartRenderer * @param sciChartSurface The {@link SciChartSurface} that we are rendering */ function SciChartRenderer(sciChartSurface) { this.isInvalidated = false; /** * Used internally to track requestAnimationFrame for svg rendering. * When `undefined` there is no pending RAF. */ this.svgRenderRequestId = undefined; this.domRenderRun = false; this.sciChartSurface = sciChartSurface; } SciChartRenderer.prototype.renderDomOnly = function () { var _this = this; var _a; if (this.sciChartSurface.isDeleted) { return; } logger_1.Logger.debug("svg only render start"); this.domRenderRun = true; this.sciChartSurface.preRender.raiseEvent(undefined); // Animation Step var timeElapsed = this.previousTime ? Date.now() - this.previousTime : 0; this.previousTime = Date.now(); // Not worried about the apparent duplication here as we prevent animations running in full render if they have run here. var animationStartMark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.GenericAnimationStart, { contextId: this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); this.sciChartSurface.onAnimate(timeElapsed); this.sciChartSurface.genericAnimationsRun.raiseEvent(); this.domRenderRun = true; performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.GenericAnimationEnd, { contextId: this.sciChartSurface.id, relatedId: (_a = animationStartMark === null || animationStartMark === void 0 ? void 0 : animationStartMark.detail) === null || _a === void 0 ? void 0 : _a.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); this.sciChartSurface.layoutMeasured.raiseEvent(); if (this.isInvalidated) { logger_1.Logger.debug("main chart invalidated during dom prerender. Reverting to full render"); this.sciChartSurface.webAssemblyContext2D.TSRRequestDraw(); return; } var userAnnotations = this.sciChartSurface.annotations.asArray(); var modifierAnnotations = this.sciChartSurface.modifierAnnotations.asArray(); var annotations = __spreadArray(__spreadArray([], userAnnotations, true), modifierAnnotations, true); var svgAnnotations = annotations.filter(function (an) { return an.isDomAnnotation; }); if (svgAnnotations.length > 0) { this.drawSvgAnnotations(svgAnnotations, this.sciChartSurface.getCoordSvgTranslation()); } this.sciChartSurface.rendered.raiseEvent(false); this.domRenderRun = false; // Invalidate for the animations if (this.sciChartSurface.isRunningAnimation) { setTimeout(function () { return _this.sciChartSurface.invalidateElement({ svgOnly: true }); }, 0); } logger_1.Logger.debug("dom only render end"); }; /** * Render loop for the current {@SciChartSurface} * @param renderContext the {@WebGLRenderContext2D} used for drawing */ SciChartRenderer.prototype.render = function (renderContext) { var _this = this; var _a, _b, _c, _d, _e, _f, _g; if (this.sciChartSurface.isDeleted) { return; } if (this.sciChartSurface.hasInvalidState) { this.displayErrorMessage(); return; } var renderStartMark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.RenderStart, { contextId: this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); logger_1.Logger.debug("render start"); var nativeContext = renderContext.getNativeContext(); var wasmContext = this.sciChartSurface.webAssemblyContext2D; var oldBlendMode; if (!app_1.IS_TEST_ENV) { oldBlendMode = nativeContext.GetBlendMode(); nativeContext.SetBlendMode(wasmContext.eSCRTBlendMode.BlendAdditiveOneAlpha); } // Step 1 validate the chart and show errors this.validate(); if (!this.domRenderRun) { // Animation Step var timeElapsed = this.previousTime ? Date.now() - this.previousTime : 0; this.previousTime = Date.now(); var animationStartMark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.GenericAnimationStart, { contextId: this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); // allow animations to cause invalidation this.isInvalidated = false; this.sciChartSurface.onAnimate(timeElapsed); this.sciChartSurface.genericAnimationsRun.raiseEvent(); // block further invalidations this.isInvalidated = true; performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.GenericAnimationEnd, { contextId: this.sciChartSurface.id, relatedId: (_a = animationStartMark === null || animationStartMark === void 0 ? void 0 : animationStartMark.detail) === null || _a === void 0 ? void 0 : _a.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); } // Step 2 autorange x this.sciChartSurface.updateStackedCollectionAccumulatedVectors(); var autoRangeStartMark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.AutoRangeStart, { contextId: this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); this.sciChartSurface.xAxes.asArray().forEach(function (axis) { return _this.tryPerformAutoRangeOn(axis, _this.sciChartSurface); }); // Step 3 prepare render data var viewRect = (_b = this.sciChartSurface.seriesViewRect) !== null && _b !== void 0 ? _b : Rect_1.Rect.create(0, 0, renderContext.viewportSize.width, renderContext.viewportSize.height); var renderPassInfo = this.prepareSeriesRenderData(viewRect); // Step 4 autorange y using resampled data if available. this.sciChartSurface.yAxes.asArray().forEach(function (axis) { return _this.tryPerformAutoRangeOn(axis, _this.sciChartSurface); }); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.AutoRangeEnd, { contextId: this.sciChartSurface.id, relatedId: (_c = autoRangeStartMark === null || autoRangeStartMark === void 0 ? void 0 : autoRangeStartMark.detail) === null || _c === void 0 ? void 0 : _c.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); // Step 3 layout var layoutStartMark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.LayoutStart, { contextId: this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); if (SciChartSurface_1.SciChartSurface.isSubSurface(this.sciChartSurface)) { this.sciChartSurface.updateSubLayout(); } var titleOffset = this.measureTitle(renderContext); var layoutOffset = Thickness_1.Thickness.mergeAdd((_d = this.sciChartSurface.offset) !== null && _d !== void 0 ? _d : Thickness_1.Thickness.fromNumber(0), titleOffset); var seriesViewRect = this.sciChartSurface.layoutManager.layoutChart(renderContext.viewportSize, layoutOffset); this.sciChartSurface.setCoordSvgTranslation(seriesViewRect.x, seriesViewRect.y); this.resizeAnnotationRootElements(seriesViewRect); // Initialise axes coordinate calculators. Must happen after layout. this.prepareAxesRenderData(); renderContext.enqueueLayeredDraw(function () { // renderContext.SetTranslation(0, 0); _this.sciChartSurface.updateBackground(renderContext); }, this.getAbsoluteLayer(DefaultRenderLayer_1.EDefaultRenderLayer.Background)); this.layoutTitle(seriesViewRect); this.scheduleTitleDraw(renderContext); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.LayoutEnd, { contextId: this.sciChartSurface.id, relatedId: (_e = layoutStartMark === null || layoutStartMark === void 0 ? void 0 : layoutStartMark.detail) === null || _e === void 0 ? void 0 : _e.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); if (!this.sciChartSurface.isSubSurface) { this.sciChartSurface.chartModifiers.asArray().forEach(function (cm) { if (cm.modifierType !== ModifierType_1.EModifierType.Chart3DModifier) { cm.linkAxes(); } cm.onParentSurfaceLayoutComplete(); }); } if (!this.domRenderRun) { this.sciChartSurface.layoutMeasured.raiseEvent(); } // Any invalidate after this will cause a rerender this.isInvalidated = false; this.domRenderRun = false; // Draw seriesViewRect border renderContext.enqueueLayeredDraw(function () { _this.sciChartSurface.drawBorder(renderContext); }, this.getAbsoluteLayer(DefaultRenderLayer_1.EDefaultRenderLayer.AxisBandsLayer)); // Step 5 Draw X, Y axis and gridlines if (this.sciChartSurface.debugRendering) { this.drawDebugAxes(this.sciChartSurface, renderContext); } this.drawAxes(this.sciChartSurface, renderContext); // if useOrderedDrawing this.getSeriesDrawFunctions(this.sciChartSurface, renderPassInfo, renderContext); this.getAnnotationDrawFunctions(this.sciChartSurface, renderPassInfo, renderContext); // Further thought required here. This could go weird if series specifices a later surfaceRenderOrder // Perform global text layout if (this.sciChartSurface.dataLabelLayoutManager) { var dataLabelLayout = new OrderedRenderable_1.OrderedRenderable(this.sciChartSurface.getSurfaceRenderOrder(), DefaultRenderLayer_1.EDefaultRenderLayer.AxesLayer, undefined); renderPassInfo.addRenderable(dataLabelLayout, function () { var _a; var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.PerformTextLayoutStart, { contextId: _this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); _this.sciChartSurface.dataLabelLayoutManager.performTextLayout(_this.sciChartSurface, renderPassInfo); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.PerformTextLayoutEnd, { contextId: _this.sciChartSurface.id, relatedId: (_a = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _a === void 0 ? void 0 : _a.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); }); } // Draw series text // This might need to be per series - or DataLabelProvider might need to implement IOrderedRenderable var dataLabels = new OrderedRenderable_1.OrderedRenderable(this.sciChartSurface.getSurfaceRenderOrder(), DefaultRenderLayer_1.EDefaultRenderLayer.AxesLayer, undefined); renderPassInfo.addRenderable(dataLabels, function () { renderPassInfo.renderableSeriesArray.forEach(function (rs, index) { var _a; if (rs.dataLabelProvider) { var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawDataLabelsStart, { contextId: rs.id, parentContextId: _this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); rs.dataLabelProvider.draw(renderContext); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawDataLabelsEnd, { contextId: rs.id, parentContextId: _this.sciChartSurface.id, relatedId: (_a = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _a === void 0 ? void 0 : _a.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); } }); }); // ENQUEUE RENDERABLES this.enqueueRenderables(renderContext, renderPassInfo); // enqueue final font rendering after everything else for this surface. renderContext.enqueueLayeredDraw(function () { var clipRect = _this.sciChartSurface.clipRect; renderContext.resetAndClip(clipRect); renderContext.endFonts(); }, this.getAbsoluteLayer(DefaultRenderLayer_1.EDefaultRenderLayer.AxesLayer)); renderContext.enqueueLayeredDraw(function () { }, this.getAbsoluteLayer(DefaultRenderLayer_1.EDefaultRenderLayer.Foreground)); //old logic which we may make optional // Step 6 Draw annotations below the series // const userAnnotations = this.sciChartSurface.annotations.asArray(); // const modifierAnnotations = this.sciChartSurface.modifierAnnotations.asArray(); // const annotations = [...userAnnotations, ...modifierAnnotations]; // const renderContextAnnotations = annotations.filter(el => !el.isDomAnnotation) as RenderContextAnnotationBase[]; // // Draw annotations before axis // const annotationsLayerBelowAxis = this.getAbsoluteLayer(EDefaultRenderLayer.Background); // renderContext.enqueueLayeredDraw(() => { // this.drawRenderContextAnnotations( // renderContextAnnotations, // EAnnotationLayer.Background, // renderContext, // seriesViewRect // ); // }, annotationsLayerBelowAxis); // const annotationsBelowLayer = this.getAbsoluteLayer(EDefaultRenderLayer.AnnotationsBelowSeriesLayer); // renderContext.enqueueLayeredDraw(() => { // this.drawRenderContextAnnotations( // renderContextAnnotations, // EAnnotationLayer.BelowChart, // renderContext, // seriesViewRect // ); // }, annotationsBelowLayer); // const seriesLayer = this.getAbsoluteLayer(EDefaultRenderLayer.SeriesLayer); // // Step 7 Draw series. Queue series rendering after grid lines and bands, but before the axes // renderContext.enqueueLayeredDraw( // () => this.drawSeries(this.sciChartSurface, renderPassInfo, renderContext), // seriesLayer // ); // const annotationsAboveLayer = this.getAbsoluteLayer(EDefaultRenderLayer.AnnotationsAboveSeriesLayer); // // Step 8 Draw annotations above the series // renderContext.enqueueLayeredDraw(() => { // this.drawRenderContextAnnotations( // renderContextAnnotations, // EAnnotationLayer.AboveChart, // renderContext, // seriesViewRect // ); // }, annotationsAboveLayer); // // Step 8 Draw annotations above the series // const foregroundLayer = this.getAbsoluteLayer(EDefaultRenderLayer.Foreground); // renderContext.enqueueLayeredDraw(() => { // const clipRect = this.sciChartSurface.clipRect; // renderContext.SetClipRect(clipRect); // renderContext.endFonts(); // }, foregroundLayer); // // Execute rendering of queued elements // renderContext.drawLayers(); // // Step 9 Draw SVG or Html Overlays // const htmlBasedAnnotations = annotations.filter(el => el.isDomAnnotation) as DomAnnotationBase[]; // this.drawHtmlBasedAnnotations(htmlBasedAnnotations, this.sciChartSurface.getCoordSvgTranslation()); // Execute rendering of queued elements renderContext.drawLayers(); // Update watermark if (!SciChartSurface_1.SciChartSurface.isSubSurface(this.sciChartSurface)) { this.updateWatermark(renderContext, seriesViewRect); } else if (renderContext.doDraw) { this.updateWatermark(renderContext, this.sciChartSurface.parentSurface.seriesViewRect); } // Step 10 Call OnParentSurfaceRendered var postDrawActionsStartMark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.PostDrawActionsStart, { contextId: this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); this.onParentSurfaceRendered(); if (!app_1.IS_TEST_ENV) { nativeContext.SetBlendMode(oldBlendMode); } // Invalidate for the animations if (this.sciChartSurface.isRunningAnimation && this.svgRenderRequestId === undefined) { setTimeout(this.sciChartSurface.invalidateElement, 0); } performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.PostDrawActionsEnd, { contextId: this.sciChartSurface.id, relatedId: (_f = postDrawActionsStartMark === null || postDrawActionsStartMark === void 0 ? void 0 : postDrawActionsStartMark.detail) === null || _f === void 0 ? void 0 : _f.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.RenderEnd, { contextId: this.sciChartSurface.id, relatedId: (_g = renderStartMark === null || renderStartMark === void 0 ? void 0 : renderStartMark.detail) === null || _g === void 0 ? void 0 : _g.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); logger_1.Logger.debug("render end"); }; SciChartRenderer.prototype.getSeriesDrawFunctions = function (scs, renderPassInfo, renderContext) { var renderableSeriesArray = renderPassInfo.renderableSeriesArray; var viewRect = this.sciChartSurface.seriesViewRect; var clipRect = Rect_1.Rect.intersect(this.sciChartSurface.seriesViewRect, this.sciChartSurface.clipRect); var hasVerticalAxes = scs.xAxes.asArray().some(function (a) { return a.isVerticalChart; }); var isFirstSeries = true; var _loop_1 = function (rs) { if (!rs.isVisible) return "continue"; var drawFn = function () { if (hasVerticalAxes || renderPassInfo.hasOtherSeriesLayerRenderables) { renderContext.setTranslationRotationAndClip(clipRect, viewRect.x, viewRect.y); } else { // Performance optimization, we call the method only for the first renderable series if (isFirstSeries) { renderContext.setTranslationRotationAndClip(clipRect, viewRect.x, viewRect.y); } } rs.draw(renderContext, rs.getCurrentRenderPassData()); isFirstSeries = false; }; renderPassInfo.addRenderable(rs, drawFn); }; for (var _i = 0, renderableSeriesArray_1 = renderableSeriesArray; _i < renderableSeriesArray_1.length; _i++) { var rs = renderableSeriesArray_1[_i]; _loop_1(rs); } }; SciChartRenderer.prototype.getAnnotationDrawFunctions = function (scs, renderPassInfo, renderContext) { var seriesViewRect = this.sciChartSurface.seriesViewRect; var userAnnotations = this.sciChartSurface.annotations.asArray(); var modifierAnnotations = this.sciChartSurface.modifierAnnotations.asArray(); var coordSvgTranslation = this.sciChartSurface.getCoordSvgTranslation(); for (var _i = 0, userAnnotations_1 = userAnnotations; _i < userAnnotations_1.length; _i++) { var annotation = userAnnotations_1[_i]; if (annotation.isDomAnnotation) { this.getHTMLAnnotationDrawFunction(annotation, coordSvgTranslation); } else if (annotation.isVisible) { this.getRenderContextAnnotationDrawFunction(annotation, renderContext, seriesViewRect, renderPassInfo); } } for (var _a = 0, modifierAnnotations_1 = modifierAnnotations; _a < modifierAnnotations_1.length; _a++) { var annotation = modifierAnnotations_1[_a]; if (annotation.isDomAnnotation) { this.getHTMLAnnotationDrawFunction(annotation, coordSvgTranslation); } else if (annotation.isVisible) { this.getRenderContextAnnotationDrawFunction(annotation, renderContext, seriesViewRect, renderPassInfo); } } }; SciChartRenderer.prototype.getHTMLAnnotationDrawFunction = function (annotation, coordSvgTranslation) { var _a; annotation.linkAxes(); var xAxis = annotation.xAxis; var yAxis = annotation.yAxis; if (!xAxis || !yAxis) { console.error("Cannot draw annotations before axes have been configured. Add axes first, or use suspendUpdates to pause drawing until axes are available."); } else { var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawAnnotationStart, { contextId: annotation.id, parentContextId: this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); annotation.update(xAxis.getCurrentCoordinateCalculator(), yAxis.getCurrentCoordinateCalculator(), coordSvgTranslation.x / DpiHelper_1.DpiHelper.PIXEL_RATIO, coordSvgTranslation.y / DpiHelper_1.DpiHelper.PIXEL_RATIO); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawAnnotationEnd, { contextId: annotation.id, parentContextId: this.sciChartSurface.id, relatedId: (_a = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _a === void 0 ? void 0 : _a.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); } }; SciChartRenderer.prototype.getRenderContextAnnotationDrawFunction = function (annotation, renderContext, seriesViewRect, renderPassInfo) { var _this = this; var surfaceViewRect = this.sciChartSurface.viewRect; var chartViewRect = this.sciChartSurface.chartViewRect; if (annotation.isVisible) { var drawFn = function () { var _a, _b, _c; annotation.linkAxes(); var xAxis = annotation.xAxis; var yAxis = annotation.yAxis; if (!xAxis || !yAxis) { console.error("Cannot draw annotations before axes have been configured. Add axes first, or use suspendUpdates to pause drawing until axes are available."); } else if (!xAxis.parentSurface) { console.error("Cannot draw annotation ".concat((_a = annotation === null || annotation === void 0 ? void 0 : annotation.constructor) === null || _a === void 0 ? void 0 : _a.name, " with X-axis detached from sciChartSurface. Set a correct xAxisId on the annotation.")); } else if (!yAxis.parentSurface) { console.error("Cannot draw annotation ".concat((_b = annotation === null || annotation === void 0 ? void 0 : annotation.constructor) === null || _b === void 0 ? void 0 : _b.name, " with Y-axis detached from sciChartSurface. Set a correct yAxisId on the annotation.")); } else { var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawAnnotationStart, { contextId: annotation.id, parentContextId: _this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); annotation.drawWithContext(renderContext, xAxis.getCurrentCoordinateCalculator(), yAxis.getCurrentCoordinateCalculator(), seriesViewRect, surfaceViewRect, chartViewRect); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawAnnotationEnd, { contextId: annotation.id, parentContextId: _this.sciChartSurface.id, relatedId: (_c = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _c === void 0 ? void 0 : _c.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); } }; renderPassInfo.addRenderable(annotation, drawFn); } }; SciChartRenderer.prototype.enqueueRenderables = function (renderContext, renderPassInfo) { renderPassInfo.resolveNextTo(); var surfaces = Array.from(renderPassInfo.rendermap.keys()); surfaces.sort(function (a, b) { return a - b; }); for (var _i = 0, surfaces_1 = surfaces; _i < surfaces_1.length; _i++) { var surfaceNum = surfaces_1[_i]; var layers = Array.from(renderPassInfo.rendermap.get(surfaceNum).keys()); layers.sort(function (a, b) { return a - b; }); for (var _a = 0, layers_1 = layers; _a < layers_1.length; _a++) { var layerNum = layers_1[_a]; var layer = renderPassInfo.rendermap.get(surfaceNum).get(layerNum); layer.sort(function (a, b) { return a.resolvedOrder - b.resolvedOrder; }); var drawLayer = (0, WebGlRenderContext2D_1.calculateAbsoluteRenderLayer)(surfaceNum, this.sciChartSurface.stepBetweenLayers, layerNum); for (var _b = 0, layer_1 = layer; _b < layer_1.length; _b++) { var item = layer_1[_b]; if (item === null || item === void 0 ? void 0 : item.drawFunction) { this.enqueueRenderable(renderContext, item, drawLayer); } } } } }; SciChartRenderer.prototype.enqueueRenderable = function (renderContext, item, absoluteLayer) { renderContext.enqueueLayeredDraw(item.drawFunction, absoluteLayer); }; SciChartRenderer.prototype.displayErrorMessage = function () { var errorDialog = document.createElement("div"); errorDialog.style.width = "100%"; errorDialog.style.height = "100%"; errorDialog.style.color = "white"; errorDialog.style.background = "black"; errorDialog.style.display = "flex"; errorDialog.style.justifyContent = "center"; errorDialog.style.alignItems = "center"; var errorMessage = document.createElement("span"); errorMessage.innerText = "The surface with id ".concat(this.sciChartSurface.id, " has an invalid state. Check the console for errors."); errorDialog.appendChild(errorMessage); this.sciChartSurface.domDivContainer.style.background = "black"; this.sciChartSurface.domDivContainer.appendChild(errorDialog); }; SciChartRenderer.prototype.drawRenderContextAnnotations = function (annotations, annotationLayer, renderContext, seriesViewRect) { var _this = this; var surfaceViewRect = this.sciChartSurface.viewRect; var chartViewRect = this.sciChartSurface.chartViewRect; annotations .filter(function (a) { return a.annotationLayer === annotationLayer; }) .forEach(function (a) { var _a; a.linkAxes(); var xAxis = a.xAxis; var yAxis = a.yAxis; if (!xAxis || !yAxis) { console.error("Cannot draw annotations before axes have been configured. Add axes first, or use suspendUpdates to pause drawing until axes are available."); } else { if (!a.isHidden) { var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawAnnotationStart, { contextId: a.id, parentContextId: _this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); a.drawWithContext(renderContext, xAxis.getCurrentCoordinateCalculator(), yAxis.getCurrentCoordinateCalculator(), seriesViewRect, surfaceViewRect, chartViewRect); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawAnnotationEnd, { contextId: a.id, parentContextId: _this.sciChartSurface.id, relatedId: (_a = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _a === void 0 ? void 0 : _a.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); } } }); }; SciChartRenderer.prototype.drawHtmlBasedAnnotations = function (annotations, coordSvgTranslation) { var _this = this; annotations.forEach(function (a) { var _a; a.linkAxes(); var xAxis = a.xAxis; var yAxis = a.yAxis; if (!xAxis || !yAxis) { console.error("Cannot draw annotations before axes have been configured. Add axes first, or use suspendUpdates to pause drawing until axes are available."); } else { var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawAnnotationStart, { contextId: _this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); a.update(xAxis.getCurrentCoordinateCalculator(), yAxis.getCurrentCoordinateCalculator(), coordSvgTranslation.x / DpiHelper_1.DpiHelper.PIXEL_RATIO, coordSvgTranslation.y / DpiHelper_1.DpiHelper.PIXEL_RATIO); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawAnnotationEnd, { contextId: _this.sciChartSurface.id, relatedId: (_a = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _a === void 0 ? void 0 : _a.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); } }); }; SciChartRenderer.prototype.drawSvgAnnotations = function (svgAnnotations, coordSvgTranslation) { var _this = this; svgAnnotations.forEach(function (a) { var _a, _b, _c; a.linkAxes(); var xAxis = a.xAxis; var yAxis = a.yAxis; if (!xAxis || !yAxis) { console.error("Cannot draw SVG annotations before axes have been configured. Add axes first, or use suspendUpdates to pause drawing until axes are available."); return; } if (xAxis.id !== a.xAxisId || yAxis.id !== a.yAxisId) { logger_1.Logger.log("SVG Annotation ".concat((_b = (_a = a.constructor) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : "", " has mismatched axis IDs. Expected xAxisId=").concat(a.xAxisId, ", yAxisId=").concat(a.yAxisId, " but got xAxis=").concat(xAxis.id, ", yAxis=").concat(yAxis.id)); } var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawAnnotationStart, { contextId: a.id, parentContextId: _this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); a.update(xAxis.getCurrentCoordinateCalculator(), yAxis.getCurrentCoordinateCalculator(), coordSvgTranslation.x / DpiHelper_1.DpiHelper.PIXEL_RATIO, coordSvgTranslation.y / DpiHelper_1.DpiHelper.PIXEL_RATIO); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawAnnotationEnd, { contextId: a.id, parentContextId: _this.sciChartSurface.id, relatedId: (_c = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _c === void 0 ? void 0 : _c.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); }); }; SciChartRenderer.prototype.validate = function () { this.sciChartSurface.xAxes.asArray().forEach(function (axis) { return (axis.isMeasured = false); }); this.sciChartSurface.yAxes.asArray().forEach(function (axis) { return (axis.isMeasured = false); }); if (this.sciChartSurface.renderableSeries.size() > 0) { var errors = this.sciChartSurface.validateAndLink(); if (errors.length > 0) { throw new Error(errors.join("\n")); } } }; SciChartRenderer.prototype.resizeAnnotationRootElements = function (seriesViewRect) { // Convert seriesViewRect back to device pixels // e.g. at Retina display canvas size may be 400x300 but seriesViewRect size would be 800x600 var clipRect = this.sciChartSurface.clipRect; var unscaledClipRect = (0, translate_1.translateToNotScaledRect)(clipRect); var seriesViewRectInDevicePixels = Rect_1.Rect.intersect((0, translate_1.translateToNotScaledRect)(seriesViewRect), unscaledClipRect); var surfaceViewRect = this.sciChartSurface.viewRect; var surfaceViewRectInDevicePixels = Rect_1.Rect.intersect((0, translate_1.translateToNotScaledRect)(surfaceViewRect), unscaledClipRect); if (!this.prevRect || !this.prevSurfaceRect) { this.prevRect = seriesViewRectInDevicePixels; this.prevSurfaceRect = surfaceViewRectInDevicePixels; } else if (Rect_1.Rect.isEqual(this.prevRect, seriesViewRectInDevicePixels) && Rect_1.Rect.isEqual(this.prevSurfaceRect, surfaceViewRectInDevicePixels)) { return; } this.prevRect = seriesViewRectInDevicePixels; this.prevSurfaceRect = surfaceViewRect; var svgRootElement = this.sciChartSurface.domSvgContainer; if (svgRootElement) { this.sciChartSurface.setSvgClipPathDefinitions(svgRootElement, seriesViewRectInDevicePixels, surfaceViewRectInDevicePixels); } var backgroundSvgRootElement = this.sciChartSurface.domBackgroundSvgContainer; if (backgroundSvgRootElement) { this.sciChartSurface.setSvgClipPathDefinitions(backgroundSvgRootElement, seriesViewRectInDevicePixels, surfaceViewRectInDevicePixels); } var adornerRootElement = this.sciChartSurface.domSvgAdornerLayer; if (adornerRootElement) { this.sciChartSurface.setSvgClipPathDefinitions(adornerRootElement, seriesViewRectInDevicePixels, surfaceViewRectInDevicePixels); } }; SciChartRenderer.prototype.prepareAxesRenderData = function () { // Prepare XAxes this.sciChartSurface.xAxes.asArray().forEach(function (xAxis) { xAxis.prepareRenderData(); }); // Prepare YAxes this.sciChartSurface.yAxes.asArray().forEach(function (yAxis) { yAxis.prepareRenderData(); }); }; SciChartRenderer.prototype.prepareSeriesRenderData = function (seriesViewRect) { var _a, _b, _c; var seriesCount = this.sciChartSurface.renderableSeries.size(); var renderPassInfo = new RenderPassInfo_1.RenderPassInfo(seriesCount, seriesViewRect); for (var i = 0; i < this.sciChartSurface.renderableSeries.size(); i++) { var series = this.sciChartSurface.renderableSeries.get(i); // don't try and draw series with no data if (!series.isCollection && !series.dataSeries) continue; // don't try and draw deleted dataseries if (!series.isCollection && series.dataSeries.getIsDeleted()) { throw new Error("SciChartSurface.renderableSeries[index=".concat(i, "] dataSeries has been deleted. ") + "This is an invalid state for SciChart. Have you shared this DataSeries between chart surfaces?"); } var resampleSingleSeriesStartMark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.ResampleSingleSeriesStart, { contextId: series.id, parentContextId: this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); var xAxis = series.xAxis; if (!xAxis.parentSurface) { console.error("Cannot draw series ".concat((_a = series === null || series === void 0 ? void 0 : series.constructor) === null || _a === void 0 ? void 0 : _a.name, " with X-axis detached from sciChartSurface. Set a correct xAxisId on the series")); continue; } var yAxis = series.yAxis; if (!yAxis.parentSurface) { console.error("Cannot draw series ".concat((_b = series === null || series === void 0 ? void 0 : series.constructor) === null || _b === void 0 ? void 0 : _b.name, " with Y-axis detached from sciChartSurface. Set a correct yAxisId on the series")); continue; } var seriesRenderPassInfo = ExtremeResamplerHelper_1.ExtremeResamplerHelper.resampleSeries(xAxis, series, seriesViewRect); renderPassInfo.renderableSeriesArray.push(seriesRenderPassInfo.renderableSeries); var renderPassData = new RenderPassData_1.RenderPassData(seriesRenderPassInfo.indicesRange, xAxis.getCurrentCoordinateCalculator, yAxis.getCurrentCoordinateCalculator, xAxis.isVerticalChart, seriesRenderPassInfo.pointSeries, seriesRenderPassInfo.resamplingHash); // Set the renderPassData early series.setCurrentRenderPassData(renderPassData); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.ResampleSingleSeriesEnd, { contextId: series.id, parentContextId: this.sciChartSurface.id, relatedId: (_c = resampleSingleSeriesStartMark === null || resampleSingleSeriesStartMark === void 0 ? void 0 : resampleSingleSeriesStartMark.detail) === null || _c === void 0 ? void 0 : _c.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); } return renderPassInfo; }; SciChartRenderer.prototype.drawAxes = function (scs, renderContext) { scs.xAxes.asArray().forEach(function (xAxis) { xAxis.draw(renderContext); }); scs.yAxes.asArray().forEach(function (yAxis) { yAxis.draw(renderContext); }); }; SciChartRenderer.prototype.drawSeries = function (scs, renderPassInfo, renderContext) { var _this = this; var _a; var renderableSeriesArray = renderPassInfo.renderableSeriesArray; var viewRect = this.sciChartSurface.seriesViewRect; var clipRect = Rect_1.Rect.intersect(this.sciChartSurface.seriesViewRect, this.sciChartSurface.clipRect); renderContext.setTranslationRotationAndClip(clipRect, viewRect.x, viewRect.y); // Draw unselected series first renderableSeriesArray.forEach(function (rs, index) { if (rs.isVisible && !rs.isSelected && !rs.isHovered) rs.draw(renderContext, rs.getCurrentRenderPassData()); }); // Draw hovered series next renderableSeriesArray.forEach(function (rs, index) { if (rs.isVisible && rs.isHovered) rs.draw(renderContext, rs.getCurrentRenderPassData()); }); // Draw selected series at higher z-index renderableSeriesArray.forEach(function (rs, index) { if (rs.isVisible && rs.isSelected) rs.draw(renderContext, rs.getCurrentRenderPassData()); }); // Perform global text layout if (this.sciChartSurface.dataLabelLayoutManager) { var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.PerformTextLayoutStart, { contextId: this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); this.sciChartSurface.dataLabelLayoutManager.performTextLayout(this.sciChartSurface, renderPassInfo); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.PerformTextLayoutEnd, { contextId: this.sciChartSurface.id, relatedId: (_a = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _a === void 0 ? void 0 : _a.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); } // Draw series text renderableSeriesArray.forEach(function (rs, index) { var _a; if (rs.isVisible && rs.dataLabelProvider) { var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawDataLabelsStart, { contextId: rs.id, parentContextId: _this.sciChartSurface.id, level: performance_1.EPerformanceDebugLevel.Verbose }); rs.dataLabelProvider.draw(renderContext); performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawDataLabelsEnd, { contextId: rs.id, parentContextId: _this.sciChartSurface.id, relatedId: (_a = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _a === void 0 ? void 0 : _a.relatedId, level: performance_1.EPerformanceDebugLevel.Verbose }); } }); }; SciChartRenderer.prototype.drawDebugAxes = function (scs, renderContext) { renderContext.enqueueLayeredDraw(function () { scs.xAxes.asArray().forEach(function (xAxis) { xAxis.drawDebug(renderContext); }); scs.yAxes.asArray().forEach(function (yAxis) { yAxis.drawDebug(renderContext); }); }); }; SciChartRenderer.prototype.tryPerformAutoRangeOn = function (axis, sciChartSurface) { var firstRange = !axis.hasValidVisibleRange() || axis.hasDefaultVisibleRange(); var shouldAutoRange = axis.autoRange === AutoRange_1.EAutoRange.Always || (axis.autoRange === AutoRange_1.EAutoRange.Once && firstRange); if (shouldAutoRange) { // Different implementation for YAxis and XAxis because of windowing var newRange = axis.getMaximumRange(); if (!newRange.equals(axis.visibleRange)) { if (!axis.autoRangeAnimation || (firstRange && !axis.autoRangeAnimation.animateInitialRanging) || (!firstRange && !axis.autoRangeAnimation.animateSubsequentRanging)) { axis.visibleRange = newRange; } else if (!newRange.equals(axis.animatedVisibleRange)) { axis.animateVisibleRange(newRange, axis.autoRangeAnimation.duration, axis.autoRangeAnimation.easing); } } } }; SciChartRenderer.prototype.onParentSurfaceRendered = function () { var _a; if (!this.sciChartSurface.isSubSurface) { this.sciChartSurface.chartModifiers.asArray().forEach(function (cm) { if (cm.modifierType !== ModifierType_1.EModifierType.Chart3DModifier) { cm.linkAxes(); } cm.onParentSurfaceRendered(); }); } // For subCharts, run this once from the parent surface, after draw has happened (_a = this.sciChartSurface.subCharts) === null || _a === void 0 ? void 0 : _a.forEach(function (sc) { if (sc.hasInvalidState) return; sc.chartModifiers.asArray().forEach(function (cm) { cm.onParentSurfaceRendered(); }); }); }; SciChartRenderer.prototype.updateWatermark = function (renderContext, seriesViewRect) { var chartHeight = this.sciChartSurface.isCopyCanvasSurface ? SciChartSurfaceBase_1.SciChartSurfaceBase.domMasterCanvas.height : renderContext.viewportSize.height; var chartWidth = this.sciChartSurface.isCopyCanvasSurface ? SciChartSurfaceBase_1.SciChartSurfaceBase.domMasterCanvas.width : renderContext.viewportSize.width; var _a = watermarkHelpers_1.watermarkHelpers.calcPosition(chartWidth, chartHeight, this.sciChartSurface.watermarkPosition, this.sciChartSurface.watermarkRelativeToCanvas, seriesViewRect, renderContext.viewportSize), left = _a.left, bottom = _a.bottom; this.sciChartSurface.updateWatermark(left, bottom); }; SciChartRenderer.prototype.scheduleTitleDraw = function (renderContext) { var _this = this; renderContext.enqueueLayeredDraw(function () { _this.sciChartSurface.chartTitleRenderer.draw(renderContext, _this.sciChartSurface.clipRect); }, this.getAbsoluteLayer(DefaultRenderLayer_1.EDefaultRenderLayer.AnnotationsAboveSeriesLayer)); }; SciChartRenderer.prototype.measureTitle = function (renderContext) { this.sciChartSurface.chartTitleRenderer.measure(this.sciChartSurface.title, this.sciChartSurface.titleStyle, renderContext); return this.sciChartSurface.chartTitleRenderer.titleOffset; }; SciChartRenderer.prototype.layoutTitle = function (seriesViewRect) { // current surface area which will contain title var chartViewRect = this.sciChartSurface.titleStyle.placeWithinChart ? seriesViewRect : this.sciChartSurface.viewRect; // title position calculation this.sciChartSurface.chartTitleRenderer.layout(chartViewRect); }; SciChartRenderer.prototype.getAbsoluteLayer = function (relativeRenderLayer) { return (0, WebGlRenderContext2D_1.calculateAbsoluteRenderLayer)(this.sciChartSurface.getSurfaceRenderOrder(), this.sciChartSurface.stepBetweenLayers, relativeRenderLayer); }; SciChartRenderer.prototype.drawDebugSurfaceRect = function (renderContext, viewRect, wasmContext) { var vecRects = (0, NativeObject_1.getVectorRectVertex)(wasmContext); var brush = new wasmContext.SCRTSolidBrush((0, parseColor_1.parseColorToUIntArgb)("rgb