| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- /* *
- *
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
- *
- * */
- 'use strict';
- import ControlPoint from '../ControlPoint.js';
- import MockPoint from '../MockPoint.js';
- import Tooltip from '../../../Core/Tooltip.js';
- import U from '../../../Core/Utilities.js';
- var isObject = U.isObject, isString = U.isString, merge = U.merge, splat = U.splat;
- /**
- * An object which denots a controllable's anchor positions - relative and
- * absolute.
- *
- * @private
- * @interface Highcharts.AnnotationAnchorObject
- */ /**
- * Relative to the plot area position
- * @name Highcharts.AnnotationAnchorObject#relativePosition
- * @type {Highcharts.BBoxObject}
- */ /**
- * Absolute position
- * @name Highcharts.AnnotationAnchorObject#absolutePosition
- * @type {Highcharts.BBoxObject}
- */
- /**
- * @interface Highcharts.AnnotationControllable
- */ /**
- * @name Highcharts.AnnotationControllable#annotation
- * @type {Highcharts.Annotation}
- */ /**
- * @name Highcharts.AnnotationControllable#chart
- * @type {Highcharts.Chart}
- */ /**
- * @name Highcharts.AnnotationControllable#collection
- * @type {string}
- */ /**
- * @private
- * @name Highcharts.AnnotationControllable#controlPoints
- * @type {Array<Highcharts.AnnotationControlPoint>}
- */ /**
- * @name Highcharts.AnnotationControllable#points
- * @type {Array<Highcharts.Point>}
- */
- /* eslint-disable no-invalid-this, valid-jsdoc */
- /**
- * It provides methods for handling points, control points
- * and points transformations.
- *
- * @private
- * @mixin
- * @name Highcharts.AnnotationControllableMixin
- */
- var controllableMixin = {
- /**
- * Init the controllable
- */
- init: function (annotation, options, index) {
- this.annotation = annotation;
- this.chart = annotation.chart;
- this.options = options;
- this.points = [];
- this.controlPoints = [];
- this.index = index;
- this.linkPoints();
- this.addControlPoints();
- },
- /**
- * Redirect attr usage on the controllable graphic element.
- */
- attr: function () {
- this.graphic.attr.apply(this.graphic, arguments);
- },
- /**
- * Get the controllable's points options.
- *
- * @return {Array<Highcharts.PointOptionsObject>}
- * An array of points' options.
- */
- getPointsOptions: function () {
- var options = this.options;
- return (options.points || (options.point && splat(options.point)));
- },
- /**
- * Utility function for mapping item's options
- * to element's attribute
- *
- * @param {Highcharts.AnnotationsLabelsOptions|Highcharts.AnnotationsShapesOptions} options
- *
- * @return {Highcharts.SVGAttributes}
- * Mapped options.
- */
- attrsFromOptions: function (options) {
- var map = this.constructor.attrsMap, attrs = {}, key, mappedKey, styledMode = this.chart.styledMode;
- for (key in options) { // eslint-disable-line guard-for-in
- mappedKey = map[key];
- if (mappedKey &&
- (!styledMode ||
- ['fill', 'stroke', 'stroke-width']
- .indexOf(mappedKey) === -1)) {
- attrs[mappedKey] = options[key];
- }
- }
- return attrs;
- },
- /**
- * Returns object which denotes anchor position - relative and absolute.
- *
- * @param {Highcharts.AnnotationPointType} point
- * A point like object.
- *
- * @return {Highcharts.AnnotationAnchorObject} a controllable anchor
- */
- anchor: function (point) {
- var plotBox = point.series.getPlotBox(), chart = point.series.chart, box = point.mock ?
- point.toAnchor() :
- Tooltip.prototype.getAnchor.call({
- chart: point.series.chart
- }, point), anchor = {
- x: box[0] + (this.options.x || 0),
- y: box[1] + (this.options.y || 0),
- height: box[2] || 0,
- width: box[3] || 0
- };
- return {
- relativePosition: anchor,
- absolutePosition: merge(anchor, {
- x: anchor.x + (point.mock ? plotBox.translateX : chart.plotLeft),
- y: anchor.y + (point.mock ? plotBox.translateY : chart.plotTop)
- })
- };
- },
- /**
- * Map point's options to a point-like object.
- *
- * @param {string|Function|Highcharts.AnnotationMockPointOptionsObject|Highcharts.AnnotationPointType} pointOptions
- * Point's options.
- *
- * @param {Highcharts.AnnotationPointType} point
- * A point-like instance.
- *
- * @return {Highcharts.AnnotationPointType|null}
- * if the point is found/set returns this point, otherwise null
- */
- point: function (pointOptions, point) {
- if (pointOptions && pointOptions.series) {
- return pointOptions;
- }
- if (!point || point.series === null) {
- if (isObject(pointOptions)) {
- point = new MockPoint(this.chart, this, pointOptions);
- }
- else if (isString(pointOptions)) {
- point = this.chart.get(pointOptions) || null;
- }
- else if (typeof pointOptions === 'function') {
- var pointConfig = pointOptions.call(point, this);
- point = pointConfig.series ?
- pointConfig :
- new MockPoint(this.chart, this, pointOptions);
- }
- }
- return point;
- },
- /**
- * Find point-like objects based on points options.
- *
- * @return {Array<Annotation.PointLike>} an array of point-like objects
- */
- linkPoints: function () {
- var pointsOptions = this.getPointsOptions(), points = this.points, len = (pointsOptions && pointsOptions.length) || 0, i, point;
- for (i = 0; i < len; i++) {
- point = this.point(pointsOptions[i], points[i]);
- if (!point) {
- points.length = 0;
- return;
- }
- if (point.mock) {
- point.refresh();
- }
- points[i] = point;
- }
- return points;
- },
- /**
- * Add control points to a controllable.
- */
- addControlPoints: function () {
- var controlPointsOptions = this.options.controlPoints;
- (controlPointsOptions || []).forEach(function (controlPointOptions, i) {
- var options = merge(this.options.controlPointOptions, controlPointOptions);
- if (!options.index) {
- options.index = i;
- }
- controlPointsOptions[i] = options;
- this.controlPoints.push(new ControlPoint(this.chart, this, options));
- }, this);
- },
- /**
- * Check if a controllable should be rendered/redrawn.
- *
- * @return {boolean}
- * Whether a controllable should be drawn.
- */
- shouldBeDrawn: function () {
- return Boolean(this.points.length);
- },
- /**
- * Render a controllable.
- */
- render: function (_parentGroup) {
- this.controlPoints.forEach(function (controlPoint) {
- controlPoint.render();
- });
- },
- /**
- * Redraw a controllable.
- *
- * @param {boolean} [animation]
- */
- redraw: function (animation) {
- this.controlPoints.forEach(function (controlPoint) {
- controlPoint.redraw(animation);
- });
- },
- /**
- * Transform a controllable with a specific transformation.
- *
- * @param {string} transformation a transformation name
- * @param {number|null} cx origin x transformation
- * @param {number|null} cy origin y transformation
- * @param {number} p1 param for the transformation
- * @param {number} [p2] param for the transformation
- */
- transform: function (transformation, cx, cy, p1, p2) {
- if (this.chart.inverted) {
- var temp = cx;
- cx = cy;
- cy = temp;
- }
- this.points.forEach(function (point, i) {
- this.transformPoint(transformation, cx, cy, p1, p2, i);
- }, this);
- },
- /**
- * Transform a point with a specific transformation
- * If a transformed point is a real point it is replaced with
- * the mock point.
- *
- * @param {string} transformation a transformation name
- * @param {number|null} cx origin x transformation
- * @param {number|null} cy origin y transformation
- * @param {number} p1 param for the transformation
- * @param {number|undefined} p2 param for the transformation
- * @param {number} i index of the point
- */
- transformPoint: function (transformation, cx, cy, p1, p2, i) {
- var point = this.points[i];
- if (!point.mock) {
- point = this.points[i] = MockPoint.fromPoint(point);
- }
- point[transformation](cx, cy, p1, p2);
- },
- /**
- * Translate a controllable.
- *
- * @param {number} dx translation for x coordinate
- * @param {number} dy translation for y coordinate
- **/
- translate: function (dx, dy) {
- this.transform('translate', null, null, dx, dy);
- },
- /**
- * Translate a specific point within a controllable.
- *
- * @param {number} dx translation for x coordinate
- * @param {number} dy translation for y coordinate
- * @param {number} i index of the point
- **/
- translatePoint: function (dx, dy, i) {
- this.transformPoint('translate', null, null, dx, dy, i);
- },
- /**
- * Translate shape within controllable item.
- * Replaces `controllable.translate` method.
- *
- * @param {number} dx translation for x coordinate
- * @param {number} dy translation for y coordinate
- */
- translateShape: function (dx, dy) {
- var chart = this.annotation.chart,
- // Annotation.options
- shapeOptions = this.annotation.userOptions,
- // Chart.options.annotations
- annotationIndex = chart.annotations.indexOf(this.annotation), chartOptions = chart.options.annotations[annotationIndex];
- this.translatePoint(dx, dy, 0);
- // Options stored in:
- // - chart (for exporting)
- // - current config (for redraws)
- chartOptions[this.collection][this.index].point = this.options.point;
- shapeOptions[this.collection][this.index].point = this.options.point;
- },
- /**
- * Rotate a controllable.
- *
- * @param {number} cx origin x rotation
- * @param {number} cy origin y rotation
- * @param {number} radians
- **/
- rotate: function (cx, cy, radians) {
- this.transform('rotate', cx, cy, radians);
- },
- /**
- * Scale a controllable.
- *
- * @param {number} cx origin x rotation
- * @param {number} cy origin y rotation
- * @param {number} sx scale factor x
- * @param {number} sy scale factor y
- */
- scale: function (cx, cy, sx, sy) {
- this.transform('scale', cx, cy, sx, sy);
- },
- /**
- * Set control points' visibility.
- *
- * @param {boolean} visible
- */
- setControlPointsVisibility: function (visible) {
- this.controlPoints.forEach(function (controlPoint) {
- controlPoint.setVisibility(visible);
- });
- },
- /**
- * Destroy a controllable.
- */
- destroy: function () {
- if (this.graphic) {
- this.graphic = this.graphic.destroy();
- }
- if (this.tracker) {
- this.tracker = this.tracker.destroy();
- }
- this.controlPoints.forEach(function (controlPoint) {
- controlPoint.destroy();
- });
- this.chart = null;
- this.points = null;
- this.controlPoints = null;
- this.options = null;
- if (this.annotation) {
- this.annotation = null;
- }
- },
- /**
- * Update a controllable.
- *
- * @param {Object} newOptions
- */
- update: function (newOptions) {
- var annotation = this.annotation, options = merge(true, this.options, newOptions), parentGroup = this.graphic.parentGroup;
- this.destroy();
- this.constructor(annotation, options);
- this.render(parentGroup);
- this.redraw();
- }
- };
- export default controllableMixin;
|