scichart
Version:
Fast WebGL JavaScript Charting Library and Framework
212 lines (211 loc) • 11 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.SciChart3DRenderer = void 0;
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 watermarkHelpers_1 = require("../../utils/watermarkHelpers");
var performance_1 = require("../../utils/performance");
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 = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.RenderStart, {
contextId: this.scs.id,
level: performance_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 = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.GenericAnimationStart, {
contextId: this.scs.id,
level: performance_1.EPerformanceDebugLevel.Verbose
});
this.scs.genericAnimationsRun.raiseEvent();
this.scs.onAnimate(timeElapsed);
performance_1.PerformanceDebugHelper.mark(performance_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: performance_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 htmlBasedAnnotations = annotations.filter(function (el) { return el.isDomAnnotation; });
htmlBasedAnnotations.forEach(function (svg) {
var _a;
var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawAnnotationStart, {
contextId: svg.id,
parentContextId: _this.scs.id,
level: performance_1.EPerformanceDebugLevel.Verbose
});
svg.update(undefined, undefined, 0, 0);
performance_1.PerformanceDebugHelper.mark(performance_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: performance_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);
}
performance_1.PerformanceDebugHelper.mark(performance_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: performance_1.EPerformanceDebugLevel.Verbose
});
};
SciChart3DRenderer.prototype.updateWatermark = function () {
var chartHeight = this.scs.getMainCanvas().clientHeight;
var chartWidth = this.scs.getMainCanvas().clientWidth;
var _a = watermarkHelpers_1.watermarkHelpers.calcPosition(chartWidth, chartHeight, this.scs.watermarkPosition, true), left = _a.left, bottom = _a.bottom;
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), ")");
};