scichart
Version:
Fast WebGL JavaScript Charting Library and Framework
304 lines (303 loc) • 13.9 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSvgLayer = exports.ELayerClass = void 0;
var WebGlHelper_1 = require("../../Core/WebGlHelper");
var perfomance_1 = require("../../utils/perfomance");
var SciChartSurfaceBase_1 = require("./SciChartSurfaceBase");
var DpiHelper_1 = require("./TextureManager/DpiHelper");
var ECanvasType;
(function (ECanvasType) {
ECanvasType[ECanvasType["canvasWebGL"] = 0] = "canvasWebGL";
ECanvasType[ECanvasType["canvas2D"] = 1] = "canvas2D";
ECanvasType[ECanvasType["svg"] = 2] = "svg";
})(ECanvasType || (ECanvasType = {}));
var ELayerClass;
(function (ELayerClass) {
ELayerClass["DIV_ROOT"] = "div-root";
ELayerClass["SVG_ROOT"] = "svg-root";
ELayerClass["BACK_DIV_ROOT"] = "back-div-root";
ELayerClass["FRONT_DIV_ROOT"] = "front-div-root";
ELayerClass["BACK_SVG_ROOT"] = "back-svg-root";
ELayerClass["FRONT_SVG_ROOT"] = "front-svg-root";
ELayerClass["ADORNER_SVG_ROOT"] = "adorner-svg-root";
ELayerClass["CANVAS_ROOT"] = "canvas-root";
})(ELayerClass = exports.ELayerClass || (exports.ELayerClass = {}));
var DEFAULT_ASPECT_RATIO = 1.5;
var getCanvas2dId = function (divElementId) { return "".concat(divElementId, "_2D"); };
var getCanvasSizes = function (divWidth, divHeight, maxHeight, aspectWidth, aspectHeight) {
if (aspectWidth === void 0) { aspectWidth = 0; }
if (aspectHeight === void 0) { aspectHeight = 0; }
var aspectRatio;
if (aspectWidth && aspectHeight) {
aspectRatio = aspectWidth / aspectHeight;
}
else if (divWidth && divHeight) {
// We do not use aspect ratio if width and height is defined
aspectRatio = undefined;
}
else {
aspectRatio = DEFAULT_ASPECT_RATIO;
}
var width = Math.round(divWidth || 600);
if (aspectRatio) {
var height = Math.round(width / aspectRatio);
if (height > maxHeight) {
height = maxHeight;
}
return { width: width, height: height, aspectRatio: aspectRatio };
}
else {
var height = Math.round(divHeight);
return { width: width, height: height, aspectRatio: aspectRatio };
}
};
var getChartRootDomElement = function (divElement) {
var chartRoot = typeof divElement === "string" ? document.querySelector("#".concat(divElement)) : divElement;
if (!chartRoot) {
throw new Error("Check div element with id \"".concat(chartRoot.id, "\" exists"));
}
if (chartRoot.nodeName.toLowerCase() !== "div") {
throw new Error("Element with id \"".concat(chartRoot.id, "\" should be of type div"));
}
return chartRoot;
};
var getMaxHeight = function (divElement) {
var styleMaxHeight = divElement.style.maxHeight;
if (styleMaxHeight) {
var isPx = styleMaxHeight.includes("px");
if (isPx) {
var maxHeight = parseInt(styleMaxHeight.replace("px", ""), 10);
if (!isNaN(maxHeight)) {
return maxHeight;
}
}
}
return undefined;
};
/**
* Initialize SciChart canvases.
* @param divElementId
* @param aspectWidth - aspect ratio width, if set to 0 is auto-calculated
* @param aspectHeight - aspect ratio height, if set to 0 is auto-calculated
* @param activeCanvas - ECanvasType.canvasWebGL for sciChartSurface.createSingle, ECanvasType.canvas2D for copy canvas,
* ECanvasType.svg for SciChartPieSurface
*/
var initCanvas = function (divElement, aspectWidth, aspectHeight, activeCanvas, disableAspect, touchAction) {
var _a;
if (activeCanvas === void 0) { activeCanvas = ECanvasType.canvasWebGL; }
var mark = perfomance_1.PerformanceDebugHelper.mark(perfomance_1.EPerformanceMarkType.CanvasInitializationStart, {
level: perfomance_1.EPerformanceDebugLevel.Verbose
});
WebGlHelper_1.WebGlHelper.initialize();
DpiHelper_1.DpiHelper.initialize();
var chartRoot = getChartRootDomElement(divElement);
chartRoot.innerHTML = "";
// prevent unexpected behavior with no positioned element
if (chartRoot.style.position === "") {
chartRoot.style.position = "relative";
}
var divElementId = chartRoot.id;
var divWidth = chartRoot.offsetWidth, divHeight = chartRoot.offsetHeight;
var maxHeight = getMaxHeight(chartRoot);
var _b = getCanvasSizes(divWidth, divHeight, maxHeight, aspectWidth, aspectHeight), width = _b.width, height = _b.height, aspectRatio = _b.aspectRatio;
// if aspect ration is defined we use is to calc height
if (!disableAspect && aspectRatio) {
// @ts-ignore
chartRoot.style.aspectRatio = "".concat(aspectRatio);
}
// Background Div Root Element
var backgroundDomRoot = document.createElement("div");
backgroundDomRoot.id = "".concat(divElementId, "_background_div");
backgroundDomRoot.classList.add(ELayerClass.DIV_ROOT, ELayerClass.BACK_DIV_ROOT);
backgroundDomRoot.style.width = "100%";
backgroundDomRoot.style.height = "100%";
backgroundDomRoot.style.position = "absolute";
backgroundDomRoot.style.pointerEvents = "none";
chartRoot.appendChild(backgroundDomRoot);
// Background SVG Root Element
var backgroundSvgRootElement = (0, exports.createSvgLayer)("".concat(divElementId, "_BACKGROUND_SVG"), width, height);
backgroundSvgRootElement.style.width = "100%";
backgroundSvgRootElement.style.height = "100%";
backgroundSvgRootElement.style.pointerEvents = "none";
backgroundSvgRootElement.classList.add(ELayerClass.BACK_SVG_ROOT);
chartRoot.appendChild(backgroundSvgRootElement);
// set canvasSize for parent div because of all children in absolute
var canvasWebGL;
if (activeCanvas === ECanvasType.canvasWebGL) {
// WebGL Canvas
canvasWebGL = document.createElement("canvas");
canvasWebGL.id = "".concat(divElementId, "_WebGL");
canvasWebGL.classList.add(ELayerClass.CANVAS_ROOT);
canvasWebGL.style.position = "absolute";
canvasWebGL.style.display = "block";
canvasWebGL.style.width = "100%";
canvasWebGL.style.height = "100%";
var gl = WebGlHelper_1.WebGlHelper.getContext(canvasWebGL, {
premultipliedAlpha: true,
antialias: SciChartSurfaceBase_1.SciChartSurfaceBase.AntiAliasWebGlBackbuffer
});
chartRoot.appendChild(canvasWebGL);
}
// 2D Canvas
var canvas2D = document.createElement("canvas");
canvas2D.id = getCanvas2dId(divElementId);
canvas2D.classList.add(ELayerClass.CANVAS_ROOT);
canvas2D.style.width = "100%";
canvas2D.style.height = "100%";
DpiHelper_1.DpiHelper.setSize(canvas2D, width, height);
canvas2D.style.position = "absolute";
if (activeCanvas !== ECanvasType.canvas2D) {
canvas2D.style.pointerEvents = "none";
}
if (activeCanvas === ECanvasType.canvasWebGL) {
canvas2D.style.display = "none";
}
else {
canvas2D.style.display = "block";
}
chartRoot.appendChild(canvas2D);
// used to prevent default browser behavior on touchscreen
canvas2D.style.touchAction = touchAction !== null && touchAction !== void 0 ? touchAction : "none";
canvas2D.onselectstart = function () { return false; };
// prevents default browser behavior of dragging the selected elements
// canvas2D.ondragstart = () => false;
// SVG Root Element
var svgRootElement = (0, exports.createSvgLayer)("".concat(divElementId, "_SVG"), width, height);
svgRootElement.style.width = "100%";
svgRootElement.style.height = "100%";
if (activeCanvas !== ECanvasType.svg) {
svgRootElement.style.pointerEvents = "none";
}
svgRootElement.classList.add(ELayerClass.FRONT_SVG_ROOT);
chartRoot.appendChild(svgRootElement);
// SVG Adorner Layer
var svgAdornerLayer = (0, exports.createSvgLayer)("".concat(divElementId, "_Adorner"), width, height);
svgAdornerLayer.style.pointerEvents = "none";
svgAdornerLayer.style.width = "100%";
svgAdornerLayer.style.height = "100%";
svgAdornerLayer.style.zIndex = "1";
svgAdornerLayer.classList.add(ELayerClass.ADORNER_SVG_ROOT);
chartRoot.appendChild(svgAdornerLayer);
// Root Div Element
var divRootElement = document.createElement("div");
divRootElement.id = "".concat(divElementId, "_div");
divRootElement.classList.add(ELayerClass.DIV_ROOT, ELayerClass.FRONT_DIV_ROOT);
divRootElement.style.width = "100%";
divRootElement.style.height = "100%";
divRootElement.style.position = "relative";
divRootElement.style.pointerEvents = "none";
divRootElement.style.textAlign = "center";
chartRoot.appendChild(divRootElement);
if (activeCanvas === ECanvasType.canvasWebGL) {
canvasWebGL.addEventListener("webglcontextlost", function (event) {
console.warn("WebGL context lost. Reloading the page.");
event.preventDefault();
location.reload();
}, !1);
}
perfomance_1.PerformanceDebugHelper.mark(perfomance_1.EPerformanceMarkType.CanvasInitializationEnd, {
level: perfomance_1.EPerformanceDebugLevel.Verbose,
contextId: canvas2D.id,
relatedId: (_a = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _a === void 0 ? void 0 : _a.relatedId
});
return {
domChartRoot: chartRoot,
domCanvasWebGL: canvasWebGL,
domCanvas2D: canvas2D,
domSvgContainer: svgRootElement,
domSvgAdornerLayer: svgAdornerLayer,
domDivContainer: divRootElement,
domSeriesBackground: backgroundDomRoot,
domBackgroundSvgContainer: backgroundSvgRootElement,
aspect: aspectRatio,
disableAspect: disableAspect
};
};
var subscribeToResize = function (chartRoot, aspect, sciChartSurface, disableAspect) {
// @ts-ignore
var resizeObserver = new ResizeObserver(function (entries) {
var _loop_1 = function (entry) {
var newWidth, newHeight;
if (entry.contentRect) {
newWidth = entry.contentRect.width;
newHeight = entry.contentRect.height;
}
else if (entry.contentBoxSize) {
// @ts-ignore
if (entry.contentBoxSize.inlineSize) {
// @ts-ignore
newWidth = entry.contentBoxSize.inlineSize;
}
else if (entry.contentBoxSize[0]) {
newWidth = entry.contentBoxSize[0].inlineSize;
}
}
else {
console.error("ResizeObserver is not supported");
newWidth = 900;
}
// check max-height
var maxHeight = getMaxHeight(chartRoot);
if (maxHeight && newHeight > maxHeight) {
newHeight = maxHeight;
}
var isNotZero = newWidth !== 0 && newHeight !== 0;
var isChanged = sciChartSurface.domCanvas2D.width !== newWidth * DpiHelper_1.DpiHelper.PIXEL_RATIO ||
sciChartSurface.domCanvas2D.height !== newHeight * DpiHelper_1.DpiHelper.PIXEL_RATIO;
if (isNotZero && isChanged) {
// We use setTimeout to fix "ResizeObserver loop limit exceeded" issue which occurs in Electron app
setTimeout(function () {
perfomance_1.PerformanceDebugHelper.mark(perfomance_1.EPerformanceMarkType.Resize, { contextId: sciChartSurface.id });
sciChartSurface.changeViewportSize(newWidth, newHeight);
}, 0);
}
};
for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
var entry = entries_1[_i];
_loop_1(entry);
}
});
resizeObserver.observe(chartRoot, { box: "border-box" });
// Return an IDeletable which will unsubscribe
var unsub = { delete: function () { return resizeObserver.disconnect(); } };
return unsub;
};
/**
* Check DOM element with specified ID exists and unique
* @param divElementId
*/
var checkChartDivExists = function (divElement) {
if (typeof divElement === "string") {
var numberOfElements = document.querySelectorAll("[id=".concat(divElement, "]")).length;
if (numberOfElements > 1) {
console.error("Please provide a unique ID for each chart div element, \"".concat(divElement, "\" it is not a unique identifier"));
}
else if (numberOfElements === 0) {
console.error("Chart div element with the ID \"".concat(divElement, "\" is not present in the DOM"));
}
}
else if (!divElement) {
throw new Error("Provided div element doesn't exist!");
}
};
var createSvgLayer = function (id, width, height) {
var svgRootElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svgRootElement.id = id;
svgRootElement.setAttribute("width", width.toString());
svgRootElement.setAttribute("height", height.toString());
svgRootElement.setAttribute("role", "img");
svgRootElement.setAttribute("xmlns", "http://www.w3.org/2000/svg");
svgRootElement.style.position = "absolute";
svgRootElement.style.display = "block";
svgRootElement.classList.add(ELayerClass.SVG_ROOT);
return svgRootElement;
};
exports.createSvgLayer = createSvgLayer;
var sciChartInitCommon = {
checkChartDivExists: checkChartDivExists,
ECanvasType: ECanvasType,
getCanvas2dId: getCanvas2dId,
initCanvas: initCanvas,
subscribeToResize: subscribeToResize
};
exports.default = sciChartInitCommon;
;