UNPKG

@wcardinal/wcardinal-geditor

Version:

WebGL-based graphic editor, tester and viewer for supervisory systems

463 lines 19.3 kB
import { __extends } from "tslib"; import { NumberFormatters, EShapeActionRuntimeBase, EShapeLockPart } from "@wcardinal/wcardinal-ui"; import { EShapeChartLine } from "./e-shape-chart-line"; import { EShapeChartLineIds } from "./e-shape-chart-line-ids"; import { UtilShapeSearch } from "../../util/util-shape-search"; var EShapeChartLineActionRuntime = /** @class */ (function (_super) { __extends(EShapeChartLineActionRuntime, _super); function EShapeChartLineActionRuntime(shape) { var _this = _super.call(this) || this; // Lines var line = UtilShapeSearch.findChildById(shape, "line"); if (line != null) { var data = shape.data; if (data.size() <= 0) { line.detach(); _this.lines = []; } else { var lines = [line]; for (var i = 1, imax = data.size(); i < imax; ++i) { var cloned = line.clone(); cloned.attach(shape); lines.push(cloned); } _this.lines = lines; } } else { _this.lines = []; } // Ticks var xmajorCount = 3; var ymajorCount = 3; var xminorCount = 3; var yminorCount = 3; if (shape instanceof EShapeChartLine) { xmajorCount = shape.axis.x.tick.major.count; ymajorCount = shape.axis.y.tick.major.count; xminorCount = shape.axis.x.tick.minor.count; yminorCount = shape.axis.y.tick.minor.count; } _this.xmajorCount = xmajorCount; _this.ymajorCount = ymajorCount; _this.xminorCount = xminorCount; _this.yminorCount = yminorCount; _this.xmajors = _this.initTicks(shape, EShapeChartLineIds.X_AXIS_TICK_MAJOR_ID, xmajorCount); _this.ymajors = _this.initTicks(shape, EShapeChartLineIds.Y_AXIS_TICK_MAJOR_ID, ymajorCount); _this.xminors = _this.initTicks(shape, EShapeChartLineIds.X_AXIS_TICK_MINOR_ID, (xmajorCount + 1) * xminorCount); _this.yminors = _this.initTicks(shape, EShapeChartLineIds.Y_AXIS_TICK_MINOR_ID, (ymajorCount + 1) * yminorCount); _this.workMajorPositions = new Float64Array(Math.max(xmajorCount, ymajorCount)); // Tick format var xtick = UtilShapeSearch.findChildById(shape, EShapeChartLineIds.X_AXIS_TICK_MAJOR_ID); _this.xformatter = NumberFormatters.create(xtick != null ? xtick.text.value : ""); var ytick = UtilShapeSearch.findChildById(shape, EShapeChartLineIds.Y_AXIS_TICK_MAJOR_ID); _this.yformatter = NumberFormatters.create(ytick != null ? ytick.text.value : ""); // Plot area _this.plotArea = UtilShapeSearch.findChildById(shape, "plot-area"); // Padding var xpadding = 10; var ypadding = 10; if (shape instanceof EShapeChartLine) { xpadding = shape.axis.x.padding; ypadding = shape.axis.y.padding; } _this.xpadding = xpadding; _this.ypadding = ypadding; return _this; } EShapeChartLineActionRuntime.prototype.initTicks = function (shape, id, count) { var tick = UtilShapeSearch.findChildById(shape, id); if (tick != null) { if (count <= 0) { tick.detach(); return []; } else { var ticks = [tick]; for (var i = 1; i < count; ++i) { var cloned = tick.clone(); cloned.attach(shape); ticks.push(cloned); } return ticks; } } else { return []; } }; EShapeChartLineActionRuntime.prototype.toStepScale = function (scale) { if (5.5 <= scale) { return 10; } else if (2.2 <= scale) { return 5; } else if (1.1 <= scale) { return 2; } return 1; }; EShapeChartLineActionRuntime.prototype.getStep = function (min, max, count) { if (count <= 0 || max <= min) { return -1; } // Calculate the step var span = (max - min) / count; var power = Math.floor(Math.log(span) / Math.LN10); var base = Math.pow(10, power); return this.toStepScale(span / base) * base; }; EShapeChartLineActionRuntime.prototype.getTickPositions = function (min, max, count, step, padding, ratio, result) { if (count <= 0) { return result; } if (max <= min || step <= 0) { result[0] = min; for (var i = 1; i < count; ++i) { result[i] = NaN; } return result; } // Set positions var start = min / step; var istart = Math.floor(start); var dstart = start - istart; if (padding < dstart * step * ratio) { istart = Math.ceil(start); } var stop = max / step; var istop = Math.ceil(stop); var dstop = istop - stop; if (padding < dstop * step * ratio) { istop = Math.floor(stop); } var nticks = Math.min(count, Math.ceil(istop - istart + 1)); for (var i = 0; i < nticks; ++i) { result[i] = (istart + i) * step; } for (var i = nticks; i < count; ++i) { result[i] = NaN; } // return result; }; EShapeChartLineActionRuntime.prototype.updateTicksXMinor = function (mstep, index, position, min, ratio, lmin, lmax) { var mticks = this.xminors; if (0 < mticks.length) { var minorCount = this.xminorCount; if (0 < mstep) { var padding = this.xpadding; if (index < 0) { for (var i = 0, j = (index + 1) * minorCount; i < minorCount; i += 1, j += 1) { var mtick = mticks[j]; var x = (position - (minorCount - i) * mstep - min) * ratio + lmin; if (lmin - padding <= x) { mtick.lock(EShapeLockPart.UPLOADED); mtick.visible = true; mtick.transform.position.x = x; mtick.unlock(EShapeLockPart.UPLOADED, true); } else { mtick.visible = false; } } } else { for (var i = 0, j = (index + 1) * minorCount; i < minorCount; i += 1, j += 1) { var mtick = mticks[j]; var x = (position + (i + 1) * mstep - min) * ratio + lmin; if (x <= lmax + padding) { mtick.lock(EShapeLockPart.UPLOADED); mtick.visible = true; mtick.transform.position.x = x; mtick.unlock(EShapeLockPart.UPLOADED, true); } else { mtick.visible = false; } } } } else { for (var i = (index + 1) * minorCount, imax = i + minorCount; i < imax; ++i) { mticks[i].visible = false; } } } }; EShapeChartLineActionRuntime.prototype.toStepMinor = function (step, minorCount) { if (0 <= step) { return step / (minorCount + 1); } else { return -1; } }; EShapeChartLineActionRuntime.prototype.updateTicksX = function (min, max, ratio, lmin, lmax) { var ticks = this.xmajors; var mticks = this.xminors; var minorCount = this.xminorCount; var padding = this.xpadding; // Major tick positions var step = this.getStep(min, max, ticks.length); var positions = this.getTickPositions(min, max, ticks.length, step, padding, ratio, this.workMajorPositions); // First minors var mstep = this.toStepMinor(step, minorCount); this.updateTicksXMinor(mstep, -1, positions[0], min, ratio, lmin, lmax); // Major and minor ticks for (var i = 0, imax = ticks.length; i < imax; ++i) { var tick = ticks[i]; var position = positions[i]; if (position === position) { // Major tick tick.lock(EShapeLockPart.UPLOADED); tick.visible = true; tick.transform.position.x = (position - min) * ratio + lmin; tick.text.value = this.xformatter.format(position, step); tick.unlock(EShapeLockPart.UPLOADED, true); // Minor ticks this.updateTicksXMinor(mstep, i, positions[i], min, ratio, lmin, lmax); } else { // Major tick tick.visible = false; // Minor ticks if (0 < mticks.length) { for (var j = (i + 1) * minorCount, jmax = j + minorCount; j < jmax; ++j) { mticks[j].visible = false; } } } } }; EShapeChartLineActionRuntime.prototype.updateTicksYMinor = function (mstep, index, position, min, ratio, lmin, lmax) { var mticks = this.yminors; if (0 < mticks.length) { var minorCount = this.yminorCount; if (0 < mstep) { var padding = this.ypadding; if (index < 0) { for (var i = 0, j = (index + 1) * minorCount; i < minorCount; i += 1, j += 1) { var mtick = mticks[j]; var y = lmax - (position - (minorCount - i) * mstep - min) * ratio; if (y <= lmax + padding) { mtick.lock(EShapeLockPart.UPLOADED); mtick.visible = true; mtick.transform.position.y = y; mtick.unlock(EShapeLockPart.UPLOADED, true); } else { mtick.visible = false; } } } else { for (var i = 0, j = (index + 1) * minorCount; i < minorCount; i += 1, j += 1) { var mtick = mticks[j]; var y = lmax - (position + (i + 1) * mstep - min) * ratio; if (lmin - padding <= y) { mtick.lock(EShapeLockPart.UPLOADED); mtick.visible = true; mtick.transform.position.y = y; mtick.unlock(EShapeLockPart.UPLOADED, true); } else { mtick.visible = false; } } } } else { for (var i = (index + 1) * minorCount, imax = i + minorCount; i < imax; ++i) { mticks[i].visible = false; } } } }; EShapeChartLineActionRuntime.prototype.updateTicksY = function (min, max, ratio, lmin, lmax) { var ticks = this.ymajors; var mticks = this.yminors; var minorCount = this.yminorCount; var padding = this.ypadding; // Major tick positions var step = this.getStep(min, max, ticks.length); var positions = this.getTickPositions(min, max, ticks.length, step, padding, ratio, this.workMajorPositions); // First minors var mstep = this.toStepMinor(step, minorCount); this.updateTicksYMinor(mstep, -1, positions[0], min, ratio, lmin, lmax); // Major and minor ticks for (var i = 0, imax = ticks.length; i < imax; ++i) { var tick = ticks[i]; var position = positions[i]; if (position === position) { // Major tick tick.lock(EShapeLockPart.UPLOADED); tick.visible = true; tick.transform.position.y = lmax - (position - min) * ratio; tick.text.value = this.yformatter.format(position, step); tick.unlock(EShapeLockPart.UPLOADED, true); // Minor ticks this.updateTicksYMinor(mstep, i, positions[i], min, ratio, lmin, lmax); } else { // Major tick tick.visible = false; // Minor ticks if (0 < mticks.length) { for (var j = (i + 1) * minorCount, jmax = j + minorCount; j < jmax; ++j) { mticks[j].visible = false; } } } } }; EShapeChartLineActionRuntime.prototype.updateLines = function (data, xmin, xratio, lxmin, ymin, yratio, lymax) { var lines = this.lines; for (var i = 0, imax = Math.min(lines.length, data.size()); i < imax; ++i) { var value = data.get(i); if (value != null) { var line = lines[i]; var points = line.points; if (points != null) { var pointsValues = points.values; var valueValues = value.values; var valueValuesLength = valueValues.length; if (2 <= valueValuesLength) { var valueTimes = value.times; var valueTimesLength = valueTimes.length; if (valueTimesLength < valueValuesLength) { // Index mode for (var j = 0; j < valueValuesLength; ++j) { var index = j << 1; pointsValues[index + 0] = (j + 1 - xmin) * xratio + lxmin; pointsValues[index + 1] = lymax - (valueValues[j] - ymin) * yratio; } } else { // Time mode for (var j = 0; j < valueValuesLength; ++j) { var index = j << 1; pointsValues[index + 0] = (valueTimes[j] - xmin) * xratio + lxmin; pointsValues[index + 1] = lymax - (valueValues[j] - ymin) * yratio; } } line.lock(EShapeLockPart.UPLOADED); line.visible = true; points.values = pointsValues; line.unlock(EShapeLockPart.UPLOADED, true); } else { line.visible = false; } } } } }; EShapeChartLineActionRuntime.prototype.execute = function (shape, runtime, time) { var data = shape.data; if (data.isChanged) { // Calculate the plot range in the time-value coordinate var xmin = +Infinity; var xmax = -Infinity; var ymin = +Infinity; var ymax = -Infinity; for (var i = 0, imax = data.size(); i < imax; ++i) { var value = data.get(i); if (value != null) { var values = value.values; var valuesLength = values.length; var times = value.times; var timesLength = times.length; // X if (timesLength < valuesLength) { // Index mode if (1 < xmin) { xmin = 1; } if (xmax < valuesLength) { xmax = valuesLength; } } else { // Time mode for (var j = 0; j < timesLength; ++j) { var t = times[j]; if (t < xmin) { xmin = t; } if (xmax < t) { xmax = t; } } } // Y for (var j = 0; j < valuesLength; ++j) { var v = values[j]; if (v < ymin) { ymin = v; } if (ymax < v) { ymax = v; } } } } if (xmax < xmin) { xmin = 0; xmax = 1; } else if (xmax <= xmin) { xmax = xmin + 1; } if (ymax < ymin) { ymax = 1; ymin = 0; } else if (ymax <= ymin) { ymax = ymin + 1; } var xspan = xmax - xmin; var yspan = ymax - ymin; // Calculate plot range in the local coordinate var plotArea = this.plotArea; var size = plotArea != null ? plotArea.size : shape.size; var sx = size.x * 0.5; var sy = size.y * 0.5; var xpadding = this.xpadding; var ypadding = this.ypadding; var lxmin = -sx + xpadding; var lxmax = +sx - xpadding; var lymin = -sy + ypadding; var lymax = +sy - ypadding; if (lxmax <= lxmin) { lxmax = lxmin + 1; } if (lymax <= lymin) { lymax = lymin + 1; } var lxspan = lxmax - lxmin; var lyspan = lymax - lymin; // x (in the time-value coordinate) // lx (in the local coordinate) // lx = (x - xmin) / (xmax - xmin) * (lxmax - lxmin) + lxmin // = (x - xmin) * xratio + lxmin // where xratio := (lxmax - lxmin) / (xmax - xmin) // // Please note thay the y coordinate in the local coordinate is upside down. // Namely, ly = lymax - (y - ymin) * yratio. var xratio = lxspan / xspan; var yratio = lyspan / yspan; // X ticks this.updateTicksX(xmin, xmax, xratio, lxmin, lxmax); // Y ticks this.updateTicksY(ymin, ymax, yratio, lymin, lymax); // Lines this.updateLines(data, xmin, xratio, lxmin, ymin, yratio, lymax); } }; return EShapeChartLineActionRuntime; }(EShapeActionRuntimeBase)); export { EShapeChartLineActionRuntime }; //# sourceMappingURL=e-shape-chart-line-action-runtime.js.map