UNPKG

scichart

Version:

Fast WebGL JavaScript Charting Library and Framework

312 lines (311 loc) 13.9 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.CompositeAnnotation = void 0; var Rect_1 = require("../../../Core/Rect"); var ObservableArray_1 = require("../../../Core/ObservableArray"); var AnnotationBase_1 = require("./AnnotationBase"); var BoxAnnotation_1 = require("./BoxAnnotation"); var IAnnotation_1 = require("./IAnnotation"); var constants_1 = require("./constants"); /** * Parent annotation that groups other annotations and keeps child positions * relative to the parent box. * * `CompositeAnnotation` is intentionally much simpler than * {@link MultiPointAnnotationBase}. It does not define its own multi-point * geometry, snapping, label anchors, segment labels or drag-grip model. Instead, * it acts as a lightweight container: child annotations are attached to the same * surface, assigned this annotation as their parent and repositioned when the * composite box moves or resizes. * * Use this when several existing annotations should behave like one grouped * object. Use {@link MultiPointAnnotationBase} derived annotations when the * annotation itself is defined by multiple points and needs labels, snapping or * specialized editing handles. */ var CompositeAnnotation = /** @class */ (function (_super) { __extends(CompositeAnnotation, _super); /** * Creates a new {@link CompositeAnnotation} * @param options Configuration options. See {@link ICompositeAnnotationOptions} for details. */ function CompositeAnnotation(options) { var _this = _super.call(this, options) || this; /** @inheritdoc */ // @ts-ignore _this.type = IAnnotation_1.EAnnotationType.CompositeAnnotation; _this.children = new ObservableArray_1.ObservableArray(); _this.relativePositions = new WeakMap(); _this.isUpdatingChildren = false; if (options === null || options === void 0 ? void 0 : options.annotations) { _this.add.apply(_this, options.annotations); } return _this; } Object.defineProperty(CompositeAnnotation.prototype, "annotations", { /** * Gets the child annotations contained within this composite. * This array should be treated as read-only. */ get: function () { return this.children.asArray(); }, /** * Replaces all child annotations in the composite. * Existing children will be removed before adding the new ones. */ set: function (value) { this.clear(); if (value) { this.add.apply(this, value); } this.notifyPropertyChanged(constants_1.PROPERTY.CHILD_ANNOTATIONS); }, enumerable: false, configurable: true }); /** * Adds one or more annotations to the composite. * Duplicate or invalid annotations are ignored. * @param items Child annotation(s) to add */ CompositeAnnotation.prototype.add = function () { var _this = this; var items = []; for (var _i = 0; _i < arguments.length; _i++) { items[_i] = arguments[_i]; } var validItems = []; for (var _a = 0, items_1 = items; _a < items_1.length; _a++) { var annotation = items_1[_a]; if (annotation instanceof AnnotationBase_1.AnnotationBase && !this.children.contains(annotation)) { this.children.add(annotation); this.captureInitialPosition(annotation); validItems.push(annotation); } } if (this.parentSurface && validItems.length > 0) { validItems.forEach(function (a) { return _this.attachChild(a); }); } }; /** * Removes a child annotation from the composite. * @param annotation The child annotation to remove * @param callDeleteOnChildren When `true`, calls delete() on the removed child */ CompositeAnnotation.prototype.remove = function (annotation, callDeleteOnChildren) { if (!(annotation instanceof AnnotationBase_1.AnnotationBase)) return; if (!this.children.contains(annotation)) return; this.children.remove(annotation, callDeleteOnChildren); this.relativePositions.delete(annotation); if (this.parentSurface) { this.parentSurface.annotations.remove(annotation, callDeleteOnChildren); } }; /** * Removes all child annotations from the composite. * @param callDeleteOnChildren When true, it also deletes the child annotations, which removes the memory claimed by the child annotations. * * Default `true` */ CompositeAnnotation.prototype.clear = function (callDeleteOnChildren) { var _this = this; if (this.parentSurface) { this.children.asArray().forEach(function (c) { return _this.parentSurface.annotations.remove(c, callDeleteOnChildren); }); } this.children.clear(callDeleteOnChildren); }; /** * Sets a normalized relative position for a child annotation. * Coordinates are expressed in the range [0..1] relative to the parent bounds. * @param child The child annotation * @param x1 Normalized X1 position * @param y1 Normalized Y1 position * @param x2 Optional normalized X2 position * @param y2 Optional normalized Y2 position */ CompositeAnnotation.prototype.setChildRelativePosition = function (child, x1, y1, x2, y2) { if (!(child instanceof AnnotationBase_1.AnnotationBase)) return; if (!this.children.contains(child)) return; this.relativePositions.set(child, { x1: x1, y1: y1, x2: x2, y2: y2, isNormalized: true }); }; /** @inheritdoc */ CompositeAnnotation.prototype.onAttach = function (surface) { var _this = this; _super.prototype.onAttach.call(this, surface); this.children.asArray().forEach(function (child) { return _this.attachChild(child); }); this.syncPropertiesToChildren(); }; /** @inheritdoc */ CompositeAnnotation.prototype.onDetach = function () { var _this = this; if (this.parentSurface) { this.children.asArray().forEach(function (child) { return _this.parentSurface.annotations.remove(child); }); } _super.prototype.onDetach.call(this); }; /** @inheritdoc */ CompositeAnnotation.prototype.drawWithContext = function (renderContext, xCalc, yCalc, seriesViewRect, surfaceViewRect, chartViewRect) { _super.prototype.drawWithContext.call(this, renderContext, xCalc, yCalc, seriesViewRect, surfaceViewRect, chartViewRect); this.updateAllChildren(xCalc, yCalc); }; /** @inheritdoc */ CompositeAnnotation.prototype.calcDragDistance = function (xyValues) { var _a, _b; _super.prototype.calcDragDistance.call(this, xyValues); var xCalc = (_a = this.xAxis) === null || _a === void 0 ? void 0 : _a.getCurrentCoordinateCalculator(); var yCalc = (_b = this.yAxis) === null || _b === void 0 ? void 0 : _b.getCurrentCoordinateCalculator(); if (xCalc && yCalc) { this.updateAllChildren(xCalc, yCalc); } }; //internal methods CompositeAnnotation.prototype.attachChild = function (child) { var surface = this.parentSurface; if (surface.annotations.contains(child)) { surface.annotations.remove(child); } child.parentAnnotationId = this.id; child.xAxisId = this.xAxisId; child.yAxisId = this.yAxisId; child.isHidden = this.isHidden; surface.annotations.add(child); }; CompositeAnnotation.prototype.captureInitialPosition = function (child) { if (this.relativePositions.has(child)) return; this.relativePositions.set(child, { x1: Number(child.x1), y1: Number(child.y1), x2: child.x2 != null ? Number(child.x2) : undefined, y2: child.y2 != null ? Number(child.y2) : undefined, isNormalized: false }); }; CompositeAnnotation.prototype.updateAllChildren = function (xCalc, yCalc) { if (this.isUpdatingChildren || this.children.size() === 0) return; this.isUpdatingChildren = true; try { var px1 = this.getX1Coordinate(xCalc, yCalc); var py1 = this.getY1Coordinate(xCalc, yCalc); var px2 = this.getX2Coordinate(xCalc, yCalc); var py2 = this.getY2Coordinate(xCalc, yCalc); var bounds = new Rect_1.Rect(Math.min(px1, px2), Math.min(py1, py2), Math.abs(px2 - px1), Math.abs(py2 - py1)); if (bounds.width <= 0 || bounds.height <= 0) return; for (var _i = 0, _a = this.children.asArray(); _i < _a.length; _i++) { var child = _a[_i]; this.updateChildPosition(child, xCalc, yCalc, bounds); } } finally { this.isUpdatingChildren = false; } }; CompositeAnnotation.prototype.ensureNormalized = function (child, xCalc, yCalc, bounds) { var stored = this.relativePositions.get(child); if (!stored) return null; if (stored.x1 >= 0 && stored.x1 <= 1 && stored.y1 >= 0 && stored.y1 <= 1) { return stored; } if (bounds.width <= 1 || bounds.height <= 1) return null; var cx1 = xCalc.getCoordinate(stored.x1); var cy1 = yCalc.getCoordinate(stored.y1); var normalized = { x1: (cx1 - bounds.x) / bounds.width, y1: (cy1 - bounds.y) / bounds.height }; if (stored.x2 != null && stored.y2 != null) { var cx2 = xCalc.getCoordinate(stored.x2); var cy2 = yCalc.getCoordinate(stored.y2); normalized.x2 = (cx2 - bounds.x) / bounds.width; normalized.y2 = (cy2 - bounds.y) / bounds.height; } this.relativePositions.set(child, normalized); return normalized; }; CompositeAnnotation.prototype.updateChildPosition = function (child, xCalc, yCalc, parentBounds) { if (!xCalc || !yCalc) return; if (!parentBounds) { var px1 = this.getX1Coordinate(xCalc, yCalc); var py1 = this.getY1Coordinate(xCalc, yCalc); var px2 = this.getX2Coordinate(xCalc, yCalc); var py2 = this.getY2Coordinate(xCalc, yCalc); parentBounds = new Rect_1.Rect(Math.min(px1, px2), Math.min(py1, py2), Math.abs(px2 - px1), Math.abs(py2 - py1)); } var rel = this.ensureNormalized(child, xCalc, yCalc, parentBounds); if (!rel) return; child.x1 = xCalc.getDataValue(parentBounds.x + rel.x1 * parentBounds.width); child.y1 = yCalc.getDataValue(parentBounds.y + rel.y1 * parentBounds.height); if (rel.x2 != null && rel.y2 != null) { child.x2 = xCalc.getDataValue(parentBounds.x + rel.x2 * parentBounds.width); child.y2 = yCalc.getDataValue(parentBounds.y + rel.y2 * parentBounds.height); } }; CompositeAnnotation.prototype.syncPropertiesToChildren = function () { for (var _i = 0, _a = this.children.asArray(); _i < _a.length; _i++) { var child = _a[_i]; if (child.xAxisId !== this.xAxisId) child.xAxisId = this.xAxisId; if (child.yAxisId !== this.yAxisId) child.yAxisId = this.yAxisId; if (child.isHidden !== this.isHidden) child.isHidden = this.isHidden; } }; /** @inheritdoc */ CompositeAnnotation.prototype.notifyPropertyChanged = function (propertyName) { _super.prototype.notifyPropertyChanged.call(this, propertyName); if (propertyName === constants_1.PROPERTY.XAXIS_ID || propertyName === constants_1.PROPERTY.YAXIS_ID || propertyName === constants_1.PROPERTY.IS_HIDDEN) { this.syncPropertiesToChildren(); } }; /** @inheritdoc */ CompositeAnnotation.prototype.toJSON = function () { var json = _super.prototype.toJSON.call(this); var options = { annotations: this.children.asArray() }; Object.assign(json.options, options); return json; }; /** @inheritdoc */ CompositeAnnotation.prototype.delete = function () { this.clear(); _super.prototype.delete.call(this); }; return CompositeAnnotation; }(BoxAnnotation_1.BoxAnnotation)); exports.CompositeAnnotation = CompositeAnnotation;