scichart
Version:
Fast WebGL JavaScript Charting Library and Framework
824 lines • 50.4 kB
JavaScript
"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