scichart
Version:
Fast WebGL JavaScript Charting Library and Framework
267 lines (266 loc) • 17.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sciChartSubSurfaceCommon = void 0;
var performanceWarnings_1 = require("../../constants/performanceWarnings");
var Deleter_1 = require("../../Core/Deleter");
var Rect_1 = require("../../Core/Rect");
var Thickness_1 = require("../../Core/Thickness");
var SubSurfacePosition_1 = require("../../types/SubSurfacePosition");
var SubSurfacePositionCoordinateMode_1 = require("../../types/SubSurfacePositionCoordinateMode");
var object_1 = require("../../utils/object");
var parseColor_1 = require("../../utils/parseColor");
var translate_1 = require("../../utils/translate");
var BrushCache_1 = require("../Drawing/BrushCache");
var createNativeRect_1 = require("./Helpers/createNativeRect");
var NativeObject_1 = require("./Helpers/NativeObject");
function createSubSurfaceCanvases(parentSurface) {
// TODO check if it's enough for subcharts to reuse main surface canvases
// const divElementId = parentSurface.domChartRoot.id + "_" + parentSurface.subChartCounter.toString();
// const chartRoot = parentSurface.domChartRoot;
// const width = chartRoot.clientWidth;
// const height = chartRoot.clientHeight;
// // SVG Root Element
// const svgRootElement = createSvgLayer(`${divElementId}_SVG`, width, height);
// svgRootElement.style.left = "0";
// svgRootElement.style.top = "0";
// svgRootElement.style.pointerEvents = "none";
// svgRootElement.classList.add(ELayerClass.FRONT_SVG_ROOT);
// chartRoot.insertBefore(svgRootElement, parentSurface.domSvgAdornerLayer);
// // SVG Root Element
// const backgroundSvgRootElement = createSvgLayer(`${divElementId}_BACKGROUND_SVG`, width, height);
// backgroundSvgRootElement.style.left = "0";
// backgroundSvgRootElement.style.top = "0";
// backgroundSvgRootElement.style.pointerEvents = "none";
// backgroundSvgRootElement.classList.add(ELayerClass.BACK_SVG_ROOT);
// chartRoot.insertBefore(backgroundSvgRootElement, parentSurface.getMainCanvas());
// // Background Div Root Element
// const backgroundDomRoot = document.createElement("div");
// backgroundDomRoot.id = `${divElementId}_background_div`;
// backgroundDomRoot.classList.add(ELayerClass.DIV_ROOT, ELayerClass.BACK_DIV_ROOT);
// backgroundDomRoot.style.left = "0";
// backgroundDomRoot.style.top = "0";
// backgroundDomRoot.style.position = "absolute";
// backgroundDomRoot.style.pointerEvents = "none";
// chartRoot.insertBefore(backgroundDomRoot, backgroundSvgRootElement);
var canvases = {
domChartRoot: parentSurface.domChartRoot,
domCanvasWebGL: parentSurface.domCanvasWebGL,
domCanvas2D: parentSurface.domCanvas2D,
domSvgContainer: parentSurface.domSvgContainer,
domSvgAdornerLayer: parentSurface.domSvgAdornerLayer,
domDivContainer: parentSurface.domDivContainer,
domBackgroundSvgContainer: parentSurface.domBackgroundSvgContainer,
domSeriesBackground: parentSurface.domSeriesBackground
};
return canvases;
}
function getSubChartRect(sub) {
var _a = sub.renderSurface.viewportSize, width = _a.width, height = _a.height;
var _b = sub.offset, top = _b.top, left = _b.left, bottom = _b.bottom, right = _b.right;
// When resizing too fast it could happen that width < left + right or height < top + bottom and it breaks subcharts
var newWidth = width - left - right > 0 ? width - left - right : 0;
var newHeight = height - top - bottom > 0 ? height - top - bottom : 0;
return new Rect_1.Rect(left, top, newWidth, newHeight);
}
function deleteSubChart(sub, clearHtml) {
// Now, no separate canvases are created for subcharts, so no need to clean them here
// // Don't ever clear html on the parent here as it kills the drawing for all subcharts.
// if (clearHtml && sub.domChartRoot.contains(sub.domSvgContainer)) {
// sub.domChartRoot.removeChild(sub.domSvgContainer);
// }
// if (clearHtml && sub.domChartRoot.contains(sub.domBackgroundSvgContainer)) {
// sub.domChartRoot.removeChild(sub.domBackgroundSvgContainer);
// }
sub.backgroundFillBrushCache = (0, Deleter_1.deleteSafe)(sub.backgroundFillBrushCache);
}
function parseCoordinateMode(coordinateMode) {
var isArrayFormat = Array.isArray(coordinateMode);
if (!isArrayFormat) {
// the same mode for all coordinates
return [coordinateMode, coordinateMode, coordinateMode, coordinateMode];
}
else if (coordinateMode.length === 1) {
// also the same mode for all coordinates
return [coordinateMode[0], coordinateMode[0], coordinateMode[0], coordinateMode[0]];
}
else if (coordinateMode.length === 2) {
// separate modes for horizontal and vertical dimensions
return [coordinateMode[0], coordinateMode[1], coordinateMode[0], coordinateMode[1]];
}
else if (coordinateMode.length === 4) {
// each coordinate with a separate mode
return coordinateMode;
}
else {
throw new Error("Invalid subChart coordinate mode provided: ".concat(coordinateMode));
}
}
function calcPadding(sub) {
var _a = sub.parentSurface.viewRect, viewWidth = _a.width, viewHeight = _a.height;
var parsedCoordinateModes = parseCoordinateMode(sub.coordinateMode);
// defines whether any position coordinate value is bound to DataValue coordinate space
var isBoundToDataValue = sub.coordinateMode === SubSurfacePositionCoordinateMode_1.ESubSurfacePositionCoordinateMode.DataValue ||
sub.coordinateMode.includes(SubSurfacePositionCoordinateMode_1.ESubSurfacePositionCoordinateMode.DataValue);
var position = sub.subPosition;
var isXywhCoordinatesFormat = (0, object_1.hasProperties)(position, SubSurfacePosition_1.xywhFormatRequiredFieldNames);
var isLtrbCoordinatesFormat = (0, object_1.hasProperties)(position, SubSurfacePosition_1.ltrbFormatRequiredFieldNames);
var isPolygonCoordinatesFormat = (0, object_1.hasProperties)(position, SubSurfacePosition_1.polygonFormatRequiredFieldNames);
// offsets of the reference axes
var _b = sub.parentSurface.seriesViewRect, leftPadding = _b.left, topPadding = _b.top;
var _c = getReferenceCoordCalcsForSubSurface(sub), horizontalCalc = _c.horizontalCalc, verticalCalc = _c.verticalCalc, xFlipped = _c.xFlipped, yFlipped = _c.yFlipped;
if (isXywhCoordinatesFormat && isBoundToDataValue) {
var xMode = parsedCoordinateModes[0], yMode = parsedCoordinateModes[1], widthMode = parsedCoordinateModes[2], heightMode = parsedCoordinateModes[3];
var x = position.x, y = position.y, width = position.width, height = position.height;
var leftAbsolute = translateToAbsoluteCoordinate(x, xMode, viewWidth, horizontalCalc, leftPadding);
var topAbsolute = translateToAbsoluteCoordinate(y, yMode, viewHeight, verticalCalc, topPadding);
// handle case when x and width have different coordinate modes
var leftCoordInSameAsWidthMode = translateFromAbsoluteCoordinate(leftAbsolute, widthMode, viewWidth, horizontalCalc, leftPadding);
var right = xFlipped ? leftCoordInSameAsWidthMode - width : leftCoordInSameAsWidthMode + width;
var rightAbsolute = translateToAbsoluteCoordinate(right, widthMode, viewWidth, horizontalCalc, leftPadding);
// handle case when y and height have different coordinate modes
var topCoordInSameAsHeightMode = translateFromAbsoluteCoordinate(topAbsolute, heightMode, viewHeight, verticalCalc, topPadding);
var bottom = yFlipped ? topCoordInSameAsHeightMode + height : topCoordInSameAsHeightMode - height;
var bottomAbsolute = translateToAbsoluteCoordinate(bottom, heightMode, viewHeight, verticalCalc, topPadding);
return new Thickness_1.Thickness(topAbsolute, viewWidth - rightAbsolute, viewHeight - bottomAbsolute, leftAbsolute);
}
else if (isXywhCoordinatesFormat && !isBoundToDataValue) {
var xMode = parsedCoordinateModes[0], yMode = parsedCoordinateModes[1], widthMode = parsedCoordinateModes[2], heightMode = parsedCoordinateModes[3];
var x = position.x, y = position.y, width = position.width, height = position.height;
var leftAbsolute = translateToAbsoluteCoordinate(x, xMode, viewWidth);
var topAbsolute = translateToAbsoluteCoordinate(y, yMode, viewHeight);
var widthAbsolute = translateToAbsoluteCoordinate(width, widthMode, viewWidth);
var heightAbsolute = translateToAbsoluteCoordinate(height, heightMode, viewHeight);
var rightAbsolute = leftAbsolute + widthAbsolute;
var borromAbsolute = topAbsolute + heightAbsolute;
return new Thickness_1.Thickness(topAbsolute, viewWidth - rightAbsolute, viewHeight - borromAbsolute, leftAbsolute);
}
else if (isLtrbCoordinatesFormat) {
var leftMode = parsedCoordinateModes[0], topMode = parsedCoordinateModes[1], rightMode = parsedCoordinateModes[2], bottomMode = parsedCoordinateModes[3];
var left = position.left, top_1 = position.top, right = position.right, bottom = position.bottom;
var leftAbsolute = translateToAbsoluteCoordinate(left, leftMode, viewWidth, horizontalCalc, leftPadding);
var topAbsolute = translateToAbsoluteCoordinate(top_1, topMode, viewHeight, verticalCalc, topPadding);
var rightAbsolute = translateToAbsoluteCoordinate(right, rightMode, viewWidth, horizontalCalc, leftPadding);
var bottomAbsolute = translateToAbsoluteCoordinate(bottom, bottomMode, viewHeight, verticalCalc, topPadding);
return new Thickness_1.Thickness(topAbsolute, viewWidth - rightAbsolute, viewHeight - bottomAbsolute, leftAbsolute);
}
else if (isPolygonCoordinatesFormat) {
var x1Mode = parsedCoordinateModes[0], y1Mode = parsedCoordinateModes[1], x2Mode = parsedCoordinateModes[2], y2Mode = parsedCoordinateModes[3];
var x1 = position.x1, y1 = position.y1, x2 = position.x2, y2 = position.y2;
var x1Absolute = translateToAbsoluteCoordinate(x1, x1Mode, viewWidth, horizontalCalc, leftPadding);
var y1Absolute = translateToAbsoluteCoordinate(y1, y1Mode, viewHeight, verticalCalc, topPadding);
var x2Absolute = translateToAbsoluteCoordinate(x2, x2Mode, viewWidth, horizontalCalc, leftPadding);
var y2Absolute = translateToAbsoluteCoordinate(y2, y2Mode, viewHeight, verticalCalc, topPadding);
// swap sides if needed
var leftAbsolute = Math.min(x1Absolute, x2Absolute);
var topAbsolute = Math.min(y1Absolute, y2Absolute);
var rightAbsolute = Math.max(x1Absolute, x2Absolute);
var bottomAbsolute = Math.max(y1Absolute, y2Absolute);
return new Thickness_1.Thickness(topAbsolute, viewWidth - rightAbsolute, viewHeight - bottomAbsolute, leftAbsolute);
}
throw new Error("Unexpected position format or coordinate mode ".concat(sub.coordinateMode, "!"));
}
function applySciChartBackground(sub, background, renderContext) {
if (!sub.isTransparent && sub.isSubSurface) {
var nativeContext = renderContext.getNativeContext();
var viewRect = sub.viewRect;
var clipRect = Rect_1.Rect.intersect(viewRect, sub.clipRect);
renderContext.setTranslationRotationAndClip(clipRect, viewRect.x, viewRect.y);
nativeContext.SetClearColor(0, 0, 0, 0);
nativeContext.Clear();
try {
// try parse background value. throws if cannot parse html color
var brushColor = (0, parseColor_1.parseColorToUIntArgb)(background);
var vecRects = (0, NativeObject_1.getVectorRectVertex)(sub.webAssemblyContext2D);
vecRects.push_back((0, createNativeRect_1.createNativeRect)(sub.webAssemblyContext2D, viewRect.left, viewRect.top, viewRect.right, viewRect.bottom));
var brush = (0, BrushCache_1.createBrushInCache)(sub.backgroundFillBrushCache, background, 1);
renderContext.drawRects(vecRects, brush, clipRect, 0, 0);
}
catch (error) {
performanceWarnings_1.performanceWarnings.subchartBackgroundNotSimpleColor.warn();
}
}
}
function updateWrapper(sub, padding) {
if (!sub.parentSurface || !sub.subChartContainer) {
return;
}
var _a = (0, translate_1.translateToNotScaledRect)(sub.parentSurface.viewRect), viewWidth = _a.width, viewHeight = _a.height;
sub.subChartContainer.style.left = (0, translate_1.convertToHtmlPx)(padding.left);
sub.subChartContainer.style.top = (0, translate_1.convertToHtmlPx)(padding.top);
sub.subChartContainer.style.width = (0, translate_1.convertToHtmlPx)(viewWidth - padding.left - padding.right);
sub.subChartContainer.style.height = (0, translate_1.convertToHtmlPx)(viewHeight - padding.top - padding.bottom);
}
function getOffsets(sub, subChartContainer) {
var _a, _b, _c, _d;
if (!subChartContainer) {
return Thickness_1.Thickness.fromNumber(0);
}
// TODO probably we can use better selector
var leftSection = subChartContainer.getElementsByClassName(sub.leftSectionClass)[0];
var topSection = subChartContainer.getElementsByClassName(sub.topSectionClass)[0];
var rightSection = subChartContainer.getElementsByClassName(sub.rightSectionClass)[0];
var bottomSection = subChartContainer.getElementsByClassName(sub.bottomSectionClass)[0];
var leftSectionWidth = (_a = leftSection === null || leftSection === void 0 ? void 0 : leftSection.clientWidth) !== null && _a !== void 0 ? _a : 0;
var topSectionHeight = (_b = topSection === null || topSection === void 0 ? void 0 : topSection.clientHeight) !== null && _b !== void 0 ? _b : 0;
var rightSectionWidth = (_c = rightSection === null || rightSection === void 0 ? void 0 : rightSection.clientWidth) !== null && _c !== void 0 ? _c : 0;
var bottomSectionHeight = (_d = bottomSection === null || bottomSection === void 0 ? void 0 : bottomSection.clientHeight) !== null && _d !== void 0 ? _d : 0;
return new Thickness_1.Thickness((0, translate_1.translateToScaled)(topSectionHeight * sub.sectionScale), (0, translate_1.translateToScaled)(rightSectionWidth * sub.sectionScale), (0, translate_1.translateToScaled)(bottomSectionHeight * sub.sectionScale), (0, translate_1.translateToScaled)(leftSectionWidth * sub.sectionScale));
}
exports.sciChartSubSurfaceCommon = {
createSubSurfaceCanvases: createSubSurfaceCanvases,
getSubChartRect: getSubChartRect,
deleteSubChart: deleteSubChart,
calcPadding: calcPadding,
applySciChartBackground: applySciChartBackground,
updateWrapper: updateWrapper,
getOffsets: getOffsets
};
var getReferenceCoordCalcsForSubSurface = function (subSurface) {
var _a, _b;
var isBoundToDataValue = subSurface.coordinateMode === SubSurfacePositionCoordinateMode_1.ESubSurfacePositionCoordinateMode.DataValue ||
subSurface.coordinateMode.includes(SubSurfacePositionCoordinateMode_1.ESubSurfacePositionCoordinateMode.DataValue);
if (!isBoundToDataValue) {
return {};
}
var xAxis = (_a = subSurface.parentSurface.getXAxisById(subSurface.parentXAxisId)) !== null && _a !== void 0 ? _a : subSurface.parentSurface.getDefaultXAxis();
if (!xAxis) {
throw new Error("No x axis with id ".concat(subSurface.parentXAxisId, " found on parent surface"));
}
var xCoordCalc = xAxis.getCurrentCoordinateCalculator();
var yAxis = (_b = subSurface.parentSurface.getYAxisById(subSurface.parentYAxisId)) !== null && _b !== void 0 ? _b : subSurface.parentSurface.getDefaultYAxis();
if (!yAxis) {
throw new Error("No y axis with id ".concat(subSurface.parentYAxisId, " found on parent surface"));
}
var yCoordCalc = yAxis.getCurrentCoordinateCalculator();
var horizontalCalc = xAxis.isVerticalChart ? yCoordCalc : xCoordCalc;
var verticalCalc = xAxis.isVerticalChart ? xCoordCalc : yCoordCalc;
var xFlipped = xAxis.flippedCoordinates;
var yFlipped = yAxis.flippedCoordinates;
return { horizontalCalc: horizontalCalc, verticalCalc: verticalCalc, xFlipped: xFlipped, yFlipped: yFlipped };
};
function translateToAbsoluteCoordinate(value, coordinateMode, referenceSize, coordinateCalculator, axisOffset) {
switch (coordinateMode) {
case SubSurfacePositionCoordinateMode_1.ESubSurfacePositionCoordinateMode.Pixel: {
return (0, translate_1.translateToScaled)(value);
}
case SubSurfacePositionCoordinateMode_1.ESubSurfacePositionCoordinateMode.Relative: {
return referenceSize * value;
}
case SubSurfacePositionCoordinateMode_1.ESubSurfacePositionCoordinateMode.DataValue: {
return axisOffset + coordinateCalculator.getCoordinate(value);
}
}
}
function translateFromAbsoluteCoordinate(value, coordinateMode, referenceSize, coordinateCalculator, calcPadding) {
switch (coordinateMode) {
case SubSurfacePositionCoordinateMode_1.ESubSurfacePositionCoordinateMode.Pixel: {
return (0, translate_1.translateToNotScaled)(value);
}
case SubSurfacePositionCoordinateMode_1.ESubSurfacePositionCoordinateMode.Relative: {
return value / referenceSize;
}
case SubSurfacePositionCoordinateMode_1.ESubSurfacePositionCoordinateMode.DataValue: {
return coordinateCalculator.getDataValue(value - calcPadding);
}
}
}