scichart
Version:
Fast WebGL JavaScript Charting Library and Framework
414 lines (413 loc) • 20.6 kB
JavaScript
"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.PolarArcZoomModifier = void 0;
var DoubleAnimator_1 = require("../../../Core/Animations/DoubleAnimator");
var EasingFunctions_1 = require("../../../Core/Animations/EasingFunctions");
var GenericAnimation_1 = require("../../../Core/Animations/GenericAnimation");
var Deleter_1 = require("../../../Core/Deleter");
var NumberRange_1 = require("../../../Core/NumberRange");
var Point_1 = require("../../../Core/Point");
var ExecuteOn_1 = require("../../../types/ChartModifiers/ExecuteOn");
var ChartModifierType_1 = require("../../../types/ChartModifierType");
var ModifierType_1 = require("../../../types/ModifierType");
var XyDirection_1 = require("../../../types/XyDirection");
var ZoomState_1 = require("../../../types/ZoomState");
var translate_1 = require("../../../utils/translate");
var PolarArcAnnotation_1 = require("../../Visuals/Annotations/PolarArcAnnotation");
var ChartModifierBase2D_1 = require("../ChartModifierBase2D");
var constants_1 = require("../constants");
var RubberBandXyZoomModifier_1 = require("../RubberBandXyZoomModifier");
/**
* The PolarArcZoomModifier provides drag-arc segment to zoom behavior on a 2D {@link SciChartPolarSurface}
* within SciChart - High Performance {@link https://www.scichart.com/javascript-chart-features | JavaScript Charts}
* Supports flipped and not flipped X Axis
* @remarks
*
* To apply the PolarArcZoomModifier to a {@link SciChartPolarSurface} and add drag to zoom behavior,
* use the following code:
*
* ```ts
* const sciChartSurface: SciChartPolarSurface;
* sciChartSurface.chartModifiers.add(new PolarArcZoomModifier());
* ```
*
* Animation of the zoom may be controlled via the {@link PolarArcZoomModifier.isAnimated},
* {@link PolarArcZoomModifier.animationDuration} and {@link PolarArcZoomModifier.easingFunction} properties.
*
* ---
* 📚 Docs: {@link https://www.scichart.com/documentation/js/v4/2d-charts/chart-modifier-api/polar-modifiers/polar-arc-zoom-modifier/}
*/
var PolarArcZoomModifier = /** @class */ (function (_super) {
__extends(PolarArcZoomModifier, _super);
/**
* Creates an instance of a PolarArcZoomModifier
* @param options Optional parameters of type {@link IPolarArcZoomModifierOptions} used to configure the modifier
*
* ---
* 📚 Docs: {@link https://www.scichart.com/documentation/js/v4/2d-charts/chart-modifier-api/polar-modifiers/polar-arc-zoom-modifier/}
*/
function PolarArcZoomModifier(options) {
var _this = this;
var _a, _b, _c, _d, _e, _f, _g;
_this = _super.call(this, options) || this;
_this.type = ChartModifierType_1.EChart2DModifierType.PolarArcZoom;
/**
* When true, the Zoom operations are animated. See also {@link animationDuration} and {@link easingFunction}
*/
_this.isAnimated = true;
/**
* Defines the duration of animations when zooming in milliseconds
*/
_this.animationDuration = 1000;
/**
* Defines the easing function for animation. See {@link TEasingFn} for a range of functions
*/
_this.easingFunction = EasingFunctions_1.easing.outCubic;
_this.isClicked = false;
_this.fillProperty = "#42b64933";
_this.strokeProperty = "#42b64977";
_this.strokeThicknessProperty = 2;
_this.fill = (_a = options === null || options === void 0 ? void 0 : options.fill) !== null && _a !== void 0 ? _a : _this.fillProperty;
_this.stroke = (_b = options === null || options === void 0 ? void 0 : options.stroke) !== null && _b !== void 0 ? _b : _this.strokeProperty;
_this.strokeThickness = (_c = options === null || options === void 0 ? void 0 : options.strokeThickness) !== null && _c !== void 0 ? _c : _this.strokeThicknessProperty;
_this.isAnimated = (_d = options === null || options === void 0 ? void 0 : options.isAnimated) !== null && _d !== void 0 ? _d : _this.isAnimated;
_this.animationDuration = (_e = options === null || options === void 0 ? void 0 : options.animationDuration) !== null && _e !== void 0 ? _e : _this.animationDuration;
if ((options === null || options === void 0 ? void 0 : options.easingFunction) && typeof options.easingFunction === "string") {
options.easingFunction = EasingFunctions_1.easing[options.easingFunction];
}
_this.easingFunction = (_f = options === null || options === void 0 ? void 0 : options.easingFunction) !== null && _f !== void 0 ? _f : _this.easingFunction;
_this.executeCondition = (_g = options === null || options === void 0 ? void 0 : options.executeCondition) !== null && _g !== void 0 ? _g : { button: ExecuteOn_1.EExecuteOn.MouseLeftButton };
return _this;
}
Object.defineProperty(PolarArcZoomModifier.prototype, "modifierType", {
/** @inheritDoc */
get: function () {
return ModifierType_1.EModifierType.Chart2DPolarModifier;
},
enumerable: false,
configurable: true
});
/** @inheritDoc */
PolarArcZoomModifier.prototype.applyTheme = function (themeProvider) {
if (!this.testPropertyChanged(constants_1.PROPERTY.FILL)) {
this.fill = themeProvider.rubberBandFillBrush;
}
if (!this.testPropertyChanged(constants_1.PROPERTY.STROKE)) {
this.stroke = themeProvider.rubberBandStrokeBrush;
}
};
/** @inheritDoc */
PolarArcZoomModifier.prototype.onAttach = function () {
_super.prototype.onAttach.call(this);
this.handleAddArcAnnotation();
};
/** @inheritDoc */
PolarArcZoomModifier.prototype.onDetach = function () {
_super.prototype.onDetach.call(this);
this.handleRemoveArcAnnotation();
};
/** @inheritDoc */
PolarArcZoomModifier.prototype.modifierMouseDown = function (args) {
_super.prototype.modifierMouseDown.call(this, args);
if (!this.checkExecuteConditions(args).isPrimary)
return;
if (!this.isAttached) {
throw new Error("Should not call PolarArcZoomModifier.modifierMouseDown if not attached");
}
this.parentSurface.setZoomState(ZoomState_1.EZoomState.UserZooming);
var pointFromTrans = (0, translate_1.translateFromCanvasToSeriesViewRect)(args.mousePoint, this.parentSurface.seriesViewRect);
if (pointFromTrans) {
var xAxis = this.xAxis;
var yAxis = this.yAxis;
var yAxisSize = yAxis.maxRadius;
var polarP = xAxis.reverseTransform(pointFromTrans.x, pointFromTrans.y);
if (polarP.y <= yAxisSize) {
this.pointFrom = pointFromTrans;
this.polarPointFrom = this.capPolarCoordinates(polarP);
this.isClicked = true;
}
}
};
/**
* used internally, caps polar coordinates to be within visible range of angular & radial axes
* @param polarPoint
* @returns
*/
PolarArcZoomModifier.prototype.capPolarCoordinates = function (polarPoint) {
var xAxis = this.xAxis;
var yAxis = this.yAxis;
var xCoordCalc = xAxis.getCurrentCoordinateCalculator();
var yCoordCalc = yAxis.getCurrentCoordinateCalculator();
var angleData = xCoordCalc.getDataValue(polarPoint.x);
var radiusData = yCoordCalc.getDataValue(polarPoint.y);
var cappedAngleData = Math.max(xAxis.visibleRange.min, Math.min(xAxis.visibleRange.max, angleData));
var cappedRadiusData = Math.max(yAxis.visibleRange.min, Math.min(yAxis.visibleRange.max, radiusData));
return new Point_1.Point(xCoordCalc.getCoordinate(cappedAngleData), yCoordCalc.getCoordinate(cappedRadiusData));
};
PolarArcZoomModifier.prototype.getArcParams = function () {
// Vertical chart not supported for now
var xAxis = this.xAxis;
var yAxis = this.yAxis;
var xCoordCalc = xAxis.getCurrentCoordinateCalculator();
var yCoordCalc = yAxis.getCurrentCoordinateCalculator();
var polarP1 = this.polarPointFrom;
var polarP2 = this.polarPointTo;
var angleStart = Math.min(xCoordCalc.getDataValue(polarP1.x), xCoordCalc.getDataValue(polarP2.x));
var angleEnd = Math.max(xCoordCalc.getDataValue(polarP1.x), xCoordCalc.getDataValue(polarP2.x));
var radiusInner = Math.min(yCoordCalc.getDataValue(polarP1.y), yCoordCalc.getDataValue(polarP2.y));
var radiusOuter = Math.max(yCoordCalc.getDataValue(polarP1.y), yCoordCalc.getDataValue(polarP2.y));
if (this.xyDirection === XyDirection_1.EXyDirection.XDirection) {
radiusInner = yAxis.visibleRange.min;
radiusOuter = yAxis.visibleRange.max;
}
else if (this.xyDirection === XyDirection_1.EXyDirection.YDirection) {
angleStart = xAxis.visibleRange.min;
angleEnd = xAxis.visibleRange.max;
}
return {
angleStart: angleStart,
angleEnd: angleEnd,
radiusInner: radiusInner,
radiusOuter: radiusOuter
};
};
PolarArcZoomModifier.prototype.updateArcAnnotation = function (mousePoint) {
var seriesViewRect = this.parentSurface.seriesViewRect;
var pointTo = (0, translate_1.translateFromCanvasToSeriesViewRect)(mousePoint, seriesViewRect);
if (pointTo) {
this.pointTo = pointTo;
var xAxis = this.xAxis;
var unclampedPolarPointTo = xAxis.reverseTransform(pointTo.x, pointTo.y);
this.polarPointTo = this.capPolarCoordinates(unclampedPolarPointTo);
var arcParams = this.getArcParams();
this.arcAnnotation.isHidden = false;
this.arcAnnotation.x1 = arcParams.angleStart;
this.arcAnnotation.x2 = arcParams.angleEnd;
this.arcAnnotation.y1 = arcParams.radiusOuter;
this.arcAnnotation.y2 = arcParams.radiusInner;
var _a = this.calculateArcOrigin(), centerX = _a.centerX, centerY = _a.centerY;
this.arcAnnotation.centerX = centerX;
this.arcAnnotation.centerY = centerY;
return arcParams;
}
else {
return this.getArcParams();
}
};
/** @inheritDoc */
PolarArcZoomModifier.prototype.modifierMouseMove = function (args) {
_super.prototype.modifierMouseMove.call(this, args);
if (this.isClicked) {
this.updateArcAnnotation(args.mousePoint);
}
};
PolarArcZoomModifier.prototype.clear = function () {
this.pointFrom = undefined;
this.polarPointFrom = undefined;
this.pointTo = undefined;
this.polarPointTo = undefined;
this.isClicked = false;
};
/** @inheritDoc */
PolarArcZoomModifier.prototype.modifierMouseUp = function (args) {
_super.prototype.modifierMouseUp.call(this, args);
if (!this.checkExecuteConditions(args).isPrimary)
return;
if (this.isClicked) {
var arcZoomParams = this.updateArcAnnotation(args.mousePoint);
this.arcAnnotation.isHidden = true;
var dist = this.calculateDraggedDistance();
this.clear();
if (arcZoomParams && dist > RubberBandXyZoomModifier_1.RubberBandXyZoomModifier.MIN_DRAG_SENSITIVITY) {
this.performZoom(arcZoomParams);
}
}
};
Object.defineProperty(PolarArcZoomModifier.prototype, "strokeThickness", {
/**
* Gets or sets the stroke thickness for the arc segment
*/
get: function () {
return this.strokeThicknessProperty;
},
set: function (value) {
this.strokeThicknessProperty = value;
this.notifyPropertyChanged(constants_1.PROPERTY.STROKE_THICKNESS);
},
enumerable: false,
configurable: true
});
Object.defineProperty(PolarArcZoomModifier.prototype, "stroke", {
/**
* Gets or sets the stroke for arc segment
*/
get: function () {
return this.strokeProperty;
},
set: function (value) {
this.strokeProperty = value;
this.notifyPropertyChanged(constants_1.PROPERTY.STROKE);
},
enumerable: false,
configurable: true
});
Object.defineProperty(PolarArcZoomModifier.prototype, "fill", {
/**
* Gets or sets the fill color for the arc segment
*/
get: function () {
return this.fillProperty;
},
set: function (value) {
this.fillProperty = value;
this.notifyPropertyChanged(constants_1.PROPERTY.FILL);
},
enumerable: false,
configurable: true
});
/** @inheritDoc */
PolarArcZoomModifier.prototype.toJSON = function () {
var json = _super.prototype.toJSON.call(this);
var options = {
animationDuration: this.animationDuration,
easingFunction: this.easingFunction.name,
fill: this.fill,
isAnimated: this.isAnimated,
stroke: this.stroke,
strokeThickness: this.strokeThickness
};
Object.assign(json.options, options);
return json;
};
/** @inheritDoc */
PolarArcZoomModifier.prototype.delete = function () {
this.parentSurfaceProperty = undefined;
this.handleRemoveArcAnnotation();
_super.prototype.delete.call(this);
};
/**
* Performs the zoom operation on the parent Surface, using the mouse points from & to, which
* define the corners of the arc segment
*/
PolarArcZoomModifier.prototype.performZoom = function (arcZoomParams) {
var scs = this.parentSurface;
if (scs) {
var xMin1 = arcZoomParams.angleStart, xMax1 = arcZoomParams.angleEnd, yMin1 = arcZoomParams.radiusInner, yMax1 = arcZoomParams.radiusOuter;
var xAxis_1 = this.xAxis;
var yAxis_1 = this.yAxis;
var _a = xAxis_1.visibleRange, xMin0_1 = _a.min, xMax0_1 = _a.max;
var _b = yAxis_1.visibleRange, yMin0 = _b.min, yMax0 = _b.max;
// it is considered that xAxis.startAngle == yAxis.startAngle
var startAngle0_1 = xAxis_1.startAngle;
var totalAngle0_1 = xAxis_1.totalAngle;
var isXFlipped_1 = xAxis_1.flippedCoordinates;
if (this.isAnimated && this.animationDuration > 0) {
var zoomToSectorAnimation = new GenericAnimation_1.GenericAnimation({
from: { x1: xMin0_1, x2: xMax0_1, y1: yMin0, y2: yMax0 },
to: { x1: xMin1, x2: xMax1, y1: yMin1, y2: yMax1 },
duration: this.animationDuration,
ease: this.easingFunction,
onAnimate: function (from, to, progress) {
var xMinCur = DoubleAnimator_1.DoubleAnimator.interpolate(from.x1, to.x1, progress);
var xMaxCur = DoubleAnimator_1.DoubleAnimator.interpolate(from.x2, to.x2, progress);
var yMinCur = DoubleAnimator_1.DoubleAnimator.interpolate(from.y1, to.y1, progress);
var yMaxCur = DoubleAnimator_1.DoubleAnimator.interpolate(from.y2, to.y2, progress);
xAxis_1.visibleRange = new NumberRange_1.NumberRange(xMinCur, xMaxCur);
yAxis_1.visibleRange = new NumberRange_1.NumberRange(yMinCur, yMaxCur);
var startAngleCur = isXFlipped_1
? startAngle0_1 - (totalAngle0_1 * (xMaxCur - xMax0_1)) / (xMax0_1 - xMin0_1)
: startAngle0_1 + (totalAngle0_1 * (xMinCur - xMin0_1)) / (xMax0_1 - xMin0_1);
xAxis_1.startAngle = startAngleCur;
yAxis_1.startAngle = startAngleCur;
xAxis_1.totalAngle = (totalAngle0_1 * (xMaxCur - xMinCur)) / (xMax0_1 - xMin0_1);
yAxis_1.innerRadius = yMinCur / yMaxCur;
}
});
scs.addAnimation(zoomToSectorAnimation);
}
else {
xAxis_1.visibleRange = new NumberRange_1.NumberRange(xMin1, xMax1);
yAxis_1.visibleRange = new NumberRange_1.NumberRange(yMin1, yMax1);
var startAngle1 = isXFlipped_1
? startAngle0_1 - (totalAngle0_1 * (xMax1 - xMax0_1)) / (xMax0_1 - xMin0_1)
: startAngle0_1 + (totalAngle0_1 * (xMin1 - xMin0_1)) / (xMax0_1 - xMin0_1);
xAxis_1.startAngle = startAngle1;
yAxis_1.startAngle = startAngle1;
xAxis_1.totalAngle = (totalAngle0_1 * (xMax1 - xMin1)) / (xMax0_1 - xMin0_1);
yAxis_1.innerRadius = yMin1 / yMax1;
}
}
};
PolarArcZoomModifier.prototype.calculateDraggedDistance = function () {
var diffX = Math.pow((this.pointFrom.x - this.pointTo.x), 2);
var diffY = Math.pow((this.pointFrom.y - this.pointTo.y), 2);
return Math.sqrt(diffX + diffY);
};
PolarArcZoomModifier.prototype.calculateArcOrigin = function () {
var xAxis = this.xAxis;
var yAxis = this.yAxis;
// TODO: revisit when the modifier supports Vertical charts
// const angularAxis = xAxis.isAngular ? xAxis : yAxis;
var radialAxis = xAxis.isAngular ? yAxis : xAxis;
var range = radialAxis.visibleRange.max - radialAxis.visibleRange.min;
var growBy = range * (radialAxis.innerRadius / (1 - radialAxis.innerRadius));
var centerY;
if (radialAxis.flippedCoordinates) {
centerY = radialAxis.visibleRange.max;
if (radialAxis.innerRadius > 0) {
centerY += growBy;
}
}
else {
centerY = radialAxis.visibleRange.min;
if (radialAxis.innerRadius > 0) {
centerY -= growBy;
}
}
return { centerX: 0, centerY: centerY };
};
PolarArcZoomModifier.prototype.handleAddArcAnnotation = function () {
var _a = this.calculateArcOrigin(), centerX = _a.centerX, centerY = _a.centerY;
this.arcAnnotation = new PolarArcAnnotation_1.PolarArcAnnotation({
isHidden: true,
x1: 0,
x2: 1,
y2: 0,
y1: 1,
centerX: centerX,
centerY: centerY,
//axisLabelFill: this.fill, // what is it?
//axisLabelStroke: this.stroke, // what is it?
stroke: this.stroke,
strokeThickness: this.strokeThickness,
fill: this.fill,
opacity: 1,
xAxisId: this.xAxisId,
yAxisId: this.yAxisId
});
this.parentSurface.modifierAnnotations.add(this.arcAnnotation);
};
PolarArcZoomModifier.prototype.handleRemoveArcAnnotation = function () {
var _a;
(_a = this.parentSurface) === null || _a === void 0 ? void 0 : _a.modifierAnnotations.remove(this.arcAnnotation, true);
this.arcAnnotation = (0, Deleter_1.deleteSafe)(this.arcAnnotation);
};
PolarArcZoomModifier.MIN_DRAG_SENSITIVITY = 5;
return PolarArcZoomModifier;
}(ChartModifierBase2D_1.ChartModifierBase2D));
exports.PolarArcZoomModifier = PolarArcZoomModifier;