| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231 | 
							- /**
 
-  * (c) 2009-2017 Highsoft, Black Label
 
-  *
 
-  * License: www.highcharts.com/license
 
-  */
 
- 'use strict';
 
- import H from '../parts/Globals.js';
 
- import '../parts/Utilities.js';
 
- import '../parts/Chart.js';
 
- import controllableMixin from './controllable/controllableMixin.js';
 
- import ControllableRect from './controllable/ControllableRect.js';
 
- import ControllableCircle from './controllable/ControllableCircle.js';
 
- import ControllablePath from './controllable/ControllablePath.js';
 
- import ControllableImage from './controllable/ControllableImage.js';
 
- import ControllableLabel from './controllable/ControllableLabel.js';
 
- import eventEmitterMixin from './eventEmitterMixin.js';
 
- import MockPoint from './MockPoint.js';
 
- import ControlPoint from './ControlPoint.js';
 
- var merge = H.merge,
 
-     addEvent = H.addEvent,
 
-     defined = H.defined,
 
-     erase = H.erase,
 
-     find = H.find,
 
-     isString = H.isString,
 
-     pick = H.pick,
 
-     reduce = H.reduce,
 
-     splat = H.splat,
 
-     destroyObjectProperties = H.destroyObjectProperties;
 
- /* *********************************************************************
 
-  *
 
-  * ANNOTATION
 
-  *
 
-  ******************************************************************** */
 
- /**
 
-  * @typedef {
 
-  *          Annotation.ControllableCircle|
 
-  *          Annotation.ControllableImage|
 
-  *          Annotation.ControllablePath|
 
-  *          Annotation.ControllableRect
 
-  *          }
 
-  *          Annotation.Shape
 
-  */
 
- /**
 
-  * @typedef {Annotation.ControllableLabel} Annotation.Label
 
-  */
 
- /**
 
-  * An annotation class which serves as a container for items like labels or
 
-  * shapes. Created items are positioned on the chart either by linking them to
 
-  * existing points or created mock points
 
-  *
 
-  * @class
 
-  * @mixes Annotation.controllableMixin
 
-  * @mixes Annotation.eventEmitterMixin
 
-  *
 
-  * @param {Highcharts.Chart} chart a chart instance
 
-  * @param {AnnotationOptions} options the options object
 
-  */
 
- var Annotation = H.Annotation = function (chart, options) {
 
-     var labelsAndShapes;
 
-     /**
 
-      * The chart that the annotation belongs to.
 
-      *
 
-      * @type {Highcharts.Chart}
 
-      */
 
-     this.chart = chart;
 
-     /**
 
-      * The array of points which defines the annotation.
 
-      *
 
-      * @type {Array<Annotation.PointLike>}
 
-      */
 
-     this.points = [];
 
-     /**
 
-      * The array of control points.
 
-      *
 
-      * @type {Array<Annotation.ControlPoint>}
 
-      */
 
-     this.controlPoints = [];
 
-     this.coll = 'annotations';
 
-     /**
 
-      * The array of labels which belong to the annotation.
 
-      *
 
-      * @type {Array<Annotation.Label>}
 
-      */
 
-     this.labels = [];
 
-     /**
 
-      * The array of shapes which belong to the annotation.
 
-      *
 
-      * @type {Array<Annotation.Shape>}
 
-      */
 
-     this.shapes = [];
 
-     /**
 
-      * The options for the annotations.
 
-      *
 
-      * @type {AnnotationOptions}
 
-      */
 
-     // this.options = merge(this.defaultOptions, userOptions);
 
-     this.options = options;
 
-     /**
 
-      * The user options for the annotations.
 
-      *
 
-      * @type {AnnotationOptions}
 
-      */
 
-     this.userOptions = merge(true, {}, options);
 
-     // Handle labels and shapes - those are arrays
 
-     // Merging does not work with arrays (stores reference)
 
-     labelsAndShapes = this.getLabelsAndShapesOptions(
 
-         this.userOptions,
 
-         options
 
-     );
 
-     this.userOptions.labels = labelsAndShapes.labels;
 
-     this.userOptions.shapes = labelsAndShapes.shapes;
 
-     /**
 
-      * The callback that reports to the overlapping-labels module which
 
-      * labels it should account for.
 
-      *
 
-      * @name labelCollector
 
-      * @memberOf Annotation#
 
-      * @type {Function}
 
-      */
 
-     /**
 
-      * The group svg element.
 
-      *
 
-      * @name group
 
-      * @memberOf Annotation#
 
-      * @type {Highcharts.SVGElement}
 
-      */
 
-     /**
 
-      * The group svg element of the annotation's shapes.
 
-      *
 
-      * @name shapesGroup
 
-      * @memberOf Annotation#
 
-      * @type {Highcharts.SVGElement}
 
-      */
 
-     /**
 
-      * The group svg element of the annotation's labels.
 
-      *
 
-      * @name labelsGroup
 
-      * @memberOf Annotation#
 
-      * @type {Highcharts.SVGElement}
 
-      */
 
-     this.init(chart, options);
 
- };
 
- merge(
 
-     true,
 
-     Annotation.prototype,
 
-     controllableMixin,
 
-     eventEmitterMixin, /** @lends Annotation# */ {
 
-         /**
 
-          * A basic type of an annotation. It allows to add custom labels
 
-          * or shapes. The items  can be tied to points, axis coordinates
 
-          * or chart pixel coordinates.
 
-          *
 
-          * @private
 
-          * @type {Object}
 
-          * @ignore-options base, annotations.crookedLine
 
-          * @sample highcharts/annotations/basic/
 
-          *         Basic annotations
 
-          * @sample highcharts/demo/annotations/
 
-          *         Advanced annotations
 
-          * @sample highcharts/css/annotations
 
-          *         Styled mode
 
-          * @sample highcharts/annotations-advanced/controllable
 
-          *          Controllable items
 
-          * @sample {highstock} stock/annotations/fibonacci-retracements
 
-          *         Custom annotation, Fibonacci retracement
 
-          * @since 6.0.0
 
-          * @optionparent annotations.crookedLine
 
-          */
 
-         defaultOptions: {
 
-             /**
 
-              * Whether the annotation is visible.
 
-              *
 
-              * @sample highcharts/annotations/visible/
 
-              *         Set annotation visibility
 
-              */
 
-             visible: true,
 
-             /**
 
-              * Allow an annotation to be draggable by a user. Possible
 
-              * values are `"x"`, `"xy"`, `"y"` and `""` (disabled).
 
-              *
 
-              * @type {string}
 
-              * @validvalue ["x", "xy", "y", ""]
 
-              */
 
-             draggable: 'xy',
 
-             /**
 
-              * Options for annotation's labels. Each label inherits options
 
-              * from the labelOptions object. An option from the labelOptions
 
-              * can be overwritten by config for a specific label.
 
-              */
 
-             labelOptions: {
 
-                 /**
 
-                  * The alignment of the annotation's label. If right,
 
-                  * the right side of the label should be touching the point.
 
-                  *
 
-                  * @validvalue ["left", "center", "right"]
 
-                  * @sample highcharts/annotations/label-position/
 
-                  *         Set labels position
 
-                  */
 
-                 align: 'center',
 
-                 /**
 
-                  * Whether to allow the annotation's labels to overlap.
 
-                  * To make the labels less sensitive for overlapping,
 
-                  * the can be set to 0.
 
-                  *
 
-                  * @sample highcharts/annotations/tooltip-like/
 
-                  *         Hide overlapping labels
 
-                  */
 
-                 allowOverlap: false,
 
-                 /**
 
-                  * The background color or gradient for the annotation's label.
 
-                  *
 
-                  * @type {Color}
 
-                  * @sample highcharts/annotations/label-presentation/
 
-                  *         Set labels graphic options
 
-                  */
 
-                 backgroundColor: 'rgba(0, 0, 0, 0.75)',
 
-                 /**
 
-                  * The border color for the annotation's label.
 
-                  *
 
-                  * @type {Color}
 
-                  * @sample highcharts/annotations/label-presentation/
 
-                  *         Set labels graphic options
 
-                  */
 
-                 borderColor: 'black',
 
-                 /**
 
-                  * The border radius in pixels for the annotaiton's label.
 
-                  *
 
-                  * @sample highcharts/annotations/label-presentation/
 
-                  *         Set labels graphic options
 
-                  */
 
-                 borderRadius: 3,
 
-                 /**
 
-                  * The border width in pixels for the annotation's label
 
-                  *
 
-                  * @sample highcharts/annotations/label-presentation/
 
-                  *         Set labels graphic options
 
-                  */
 
-                 borderWidth: 1,
 
-                 /**
 
-                  * A class name for styling by CSS.
 
-                  *
 
-                  * @sample highcharts/css/annotations
 
-                  *         Styled mode annotations
 
-                  * @since 6.0.5
 
-                  */
 
-                 className: '',
 
-                 /**
 
-                  * Whether to hide the annotation's label
 
-                  * that is outside the plot area.
 
-                  *
 
-                  * @sample highcharts/annotations/label-crop-overflow/
 
-                  *         Crop or justify labels
 
-                  */
 
-                 crop: false,
 
-                 /**
 
-                  * The label's pixel distance from the point.
 
-                  *
 
-                  * @type {number}
 
-                  * @sample highcharts/annotations/label-position/
 
-                  *         Set labels position
 
-                  * @default undefined
 
-                  * @apioption annotations.crookedLine.labelOptions.distance
 
-                  */
 
-                 /**
 
-                  * A [format](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting) string for the data label.
 
-                  *
 
-                  * @type {string}
 
-                  * @see    [plotOptions.series.dataLabels.format](
 
-                  *         plotOptions.series.dataLabels.format.html)
 
-                  * @sample highcharts/annotations/label-text/
 
-                  *         Set labels text
 
-                  * @default undefined
 
-                  * @apioption annotations.crookedLine.labelOptions.format
 
-                  */
 
-                 /**
 
-                  * Alias for the format option.
 
-                  *
 
-                  * @type {string}
 
-                  * @see [format](annotations.labelOptions.format.html)
 
-                  * @sample highcharts/annotations/label-text/
 
-                  *         Set labels text
 
-                  * @default undefined
 
-                  * @apioption annotations.crookedLine.labelOptions.text
 
-                  */
 
-                 /**
 
-                  * Callback JavaScript function to format
 
-                  * the annotation's label. Note that if a `format` or `text`
 
-                  * are defined, the format or text take precedence and
 
-                  * the formatter is ignored. `This` refers to a * point object.
 
-                  *
 
-                  * @type {function}
 
-                  * @sample highcharts/annotations/label-text/
 
-                  *         Set labels text
 
-                  * @default function () {
 
-                  *  return defined(this.y) ? this.y : 'Annotation label';
 
-                  * }
 
-                  */
 
-                 formatter: function () {
 
-                     return defined(this.y) ? this.y : 'Annotation label';
 
-                 },
 
-                 /**
 
-                  * How to handle the annotation's label that flow
 
-                  * outside the plot area. The justify option aligns the label
 
-                  * inside the plot area.
 
-                  *
 
-                  * @validvalue ["none", "justify"]
 
-                  * @sample highcharts/annotations/label-crop-overflow/
 
-                  *         Crop or justify labels
 
-                  **/
 
-                 overflow: 'justify',
 
-                 /**
 
-                  * When either the borderWidth or the backgroundColor is set,
 
-                  * this is the padding within the box.
 
-                  *
 
-                  * @sample highcharts/annotations/label-presentation/
 
-                  *         Set labels graphic options
 
-                  */
 
-                 padding: 5,
 
-                 /**
 
-                  * The shadow of the box. The shadow can be
 
-                  * an object configuration containing
 
-                  * `color`, `offsetX`, `offsetY`, `opacity` and `width`.
 
-                  *
 
-                  * @type {Boolean|Object}
 
-                  * @sample highcharts/annotations/label-presentation/
 
-                  *         Set labels graphic options
 
-                  */
 
-                 shadow: false,
 
-                 /**
 
-                  * The name of a symbol to use for the border around the label.
 
-                  * Symbols are predefined functions on the Renderer object.
 
-                  *
 
-                  * @type {string}
 
-                  * @sample highcharts/annotations/shapes/
 
-                  *         Available shapes for labels
 
-                  */
 
-                 shape: 'callout',
 
-                 /**
 
-                  * Styles for the annotation's label.
 
-                  *
 
-                  * @type {CSSObject}
 
-                  * @sample highcharts/annotations/label-presentation/
 
-                  *         Set labels graphic options
 
-                  * @see    [plotOptions.series.dataLabels.style](
 
-                  *         plotOptions.series.dataLabels.style.html)
 
-                  */
 
-                 style: {
 
-                     fontSize: '11px',
 
-                     fontWeight: 'normal',
 
-                     color: 'contrast'
 
-                 },
 
-                 /**
 
-                  * Whether to [use HTML](http://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)
 
-                  * to render the annotation's label.
 
-                  *
 
-                  * @type {boolean}
 
-                  * @default false
 
-                  */
 
-                 useHTML: false,
 
-                 /**
 
-                  * The vertical alignment of the annotation's label.
 
-                  *
 
-                  * @type {string}
 
-                  * @validvalue ["top", "middle", "bottom"]
 
-                  * @sample highcharts/annotations/label-position/
 
-                  *         Set labels position
 
-                  */
 
-                 verticalAlign: 'bottom',
 
-                 /**
 
-                  * The x position offset of the label relative to the point.
 
-                  * Note that if a `distance` is defined, the distance takes
 
-                  * precedence over `x` and `y` options.
 
-                  *
 
-                  * @sample highcharts/annotations/label-position/
 
-                  *         Set labels position
 
-                  */
 
-                 x: 0,
 
-                 /**
 
-                  * The y position offset of the label relative to the point.
 
-                  * Note that if a `distance` is defined, the distance takes
 
-                  * precedence over `x` and `y` options.
 
-                  *
 
-                  * @sample highcharts/annotations/label-position/
 
-                  *         Set labels position
 
-                  */
 
-                 y: -16
 
-             },
 
-             /**
 
-              * An array of labels for the annotation. For options that apply to
 
-              * multiple labels, they can be added to the
 
-              * [labelOptions](annotations.labelOptions.html).
 
-              *
 
-              * @type {Array<Object>}
 
-              * @extends annotations.crookedLine.labelOptions
 
-              * @apioption annotations.crookedLine.labels
 
-              */
 
-             /**
 
-              * This option defines the point to which the label
 
-              * will be connected.
 
-              * It can be either the point which exists in the series - it is
 
-              * referenced by the point's id - or a new point with defined x, y
 
-              * properies and optionally axes.
 
-              *
 
-              * @type {string|MockPointOptions}
 
-              * @sample highcharts/annotations/mock-point/
 
-              *         Attach annotation to a mock point
 
-              * @apioption annotations.crookedLine.labels.point
 
-              */
 
-             /**
 
-              * The x position of the point. Units can be either in axis
 
-              * or chart pixel coordinates.
 
-              *
 
-              * @type {number}
 
-              * @apioption annotations.crookedLine.labels.point.x
 
-              */
 
-             /**
 
-              * The y position of the point. Units can be either in axis
 
-              * or chart pixel coordinates.
 
-              *
 
-              * @type {number}
 
-              * @apioption annotations.crookedLine.labels.point.y
 
-              */
 
-             /**
 
-              * This number defines which xAxis the point is connected to.
 
-              * It refers to either the axis id or the index of the axis
 
-              * in the xAxis array. If the option is not configured or
 
-              * the axis is not found the point's
 
-              * x coordinate refers to the chart pixels.
 
-              *
 
-              * @type {number|string}
 
-              * @apioption annotations.crookedLine.labels.point.xAxis
 
-              */
 
-             /**
 
-              * This number defines which yAxis the point is connected to.
 
-              * It refers to either the axis id or the index of the axis
 
-              * in the yAxis array. If the option is not configured or
 
-              * the axis is not found the point's
 
-              * y coordinate refers to the chart pixels.
 
-              *
 
-              * @type {number|string}
 
-              * @apioption annotations.crookedLine.labels.point.yAxis
 
-              */
 
-             /**
 
-              * An array of shapes for the annotation. For options that apply to
 
-              * multiple shapes, then can be added to the
 
-              * [shapeOptions](annotations.shapeOptions.html).
 
-              *
 
-              * @type {Array<Object>}
 
-              * @extends annotations.crookedLine.shapeOptions
 
-              * @apioption annotations.crookedLine.shapes
 
-              */
 
-             /**
 
-              * This option defines the point to which the shape will be
 
-              * connected.
 
-              * It can be either the point which exists in the series - it is
 
-              * referenced by the point's id - or a new point with defined x, y
 
-              * properties and optionally axes.
 
-              *
 
-              * @type {string|MockPointOptions}
 
-              * @extends annotations.crookedLine.labels.point
 
-              * @apioption annotations.crookedLine.shapes.point
 
-              */
 
-             /**
 
-              * An array of points for the shape. This option is available
 
-              * for shapes which can use multiple points such as path.
 
-              * A point can be either a point object or a point's id.
 
-              *
 
-              * @type {Array<string|Highcharts.MockPoint.Options>}
 
-              * @see [annotations.shapes.point](annotations.shapes.point.html)
 
-              * @apioption annotations.crookedLine.shapes.points
 
-              */
 
-             /**
 
-              * Id of the marker which will be drawn at the final
 
-              * vertex of the path.
 
-              * Custom markers can be defined in defs property.
 
-              *
 
-              * @type {string}
 
-              * @see [defs.markers](defs.markers.html)
 
-              * @sample highcharts/annotations/custom-markers/
 
-              *         Define a custom marker for annotations
 
-              * @apioption annotations.crookedLine.shapes.markerEnd
 
-              */
 
-             /**
 
-              * Id of the marker which will be drawn at the first
 
-              * vertex of the path.
 
-              * Custom markers can be defined in defs property.
 
-              *
 
-              * @type {string}
 
-              * @see [defs.markers](defs.markers.html)
 
-              * @sample {highcharts} highcharts/annotations/custom-markers/
 
-              *         Define a custom marker for annotations
 
-              * @apioption annotations.crookedLine.shapes.markerStart
 
-              */
 
-             /**
 
-              * Options for annotation's shapes. Each shape inherits options
 
-              * from the shapeOptions object. An option from the shapeOptions
 
-              * can be overwritten by config for a specific shape.
 
-              *
 
-              * @type {Object}
 
-              */
 
-             shapeOptions: {
 
-                 /**
 
-                  * The width of the shape.
 
-                  *
 
-                  * @type {number}
 
-                  * @sample highcharts/annotations/shape/
 
-                  *         Basic shape annotation
 
-                  * @apioption annotations.crookedLine.shapeOptions.width
 
-                  **/
 
-                 /**
 
-                  * The height of the shape.
 
-                  *
 
-                  * @type {number}
 
-                  * @sample highcharts/annotations/shape/
 
-                  *         Basic shape annotation
 
-                  * @apioption annotations.crookedLine.shapeOptions.height
 
-                  */
 
-                 /**
 
-                  * The color of the shape's stroke.
 
-                  *
 
-                  * @type {Color}
 
-                  * @sample highcharts/annotations/shape/
 
-                  *         Basic shape annotation
 
-                  */
 
-                 stroke: 'rgba(0, 0, 0, 0.75)',
 
-                 /**
 
-                  * The pixel stroke width of the shape.
 
-                  *
 
-                  * @sample highcharts/annotations/shape/
 
-                  *         Basic shape annotation
 
-                  */
 
-                 strokeWidth: 1,
 
-                 /**
 
-                  * The color of the shape's fill.
 
-                  *
 
-                  * @type {Color}
 
-                  * @sample highcharts/annotations/shape/
 
-                  *         Basic shape annotation
 
-                  */
 
-                 fill: 'rgba(0, 0, 0, 0.75)',
 
-                 /**
 
-                  * The type of the shape, e.g. circle or rectangle.
 
-                  *
 
-                  * @type {string}
 
-                  * @sample highcharts/annotations/shape/
 
-                  *         Basic shape annotation
 
-                  * @default 'rect'
 
-                  * @apioption annotations.crookedLine.shapeOptions.type
 
-                  */
 
-                 /**
 
-                  * The radius of the shape.
 
-                  *
 
-                  * @sample highcharts/annotations/shape/
 
-                  *         Basic shape annotation
 
-                  */
 
-                 r: 0,
 
-                 /**
 
-                  * Defines additional snapping area around an annotation
 
-                  * making this annotation to focus. Defined in pixels.
 
-                  */
 
-                 snap: 2
 
-             },
 
-             /**
 
-              * Options for annotation's control points. Each control point
 
-              * inherits options from controlPointOptions object.
 
-              * Options from the controlPointOptions can be overwritten
 
-              * by options in a specific control point.
 
-              *
 
-              * @type {Annotation.ControlPoint.Options}
 
-              * @apioption annotations.crookedLine.controlPointOptions
 
-              */
 
-             controlPointOptions: {
 
-                 symbol: 'circle',
 
-                 width: 10,
 
-                 height: 10,
 
-                 style: {
 
-                     stroke: 'black',
 
-                     'stroke-width': 2,
 
-                     fill: 'white'
 
-                 },
 
-                 visible: false,
 
-                 /**
 
-                  * @function {Annotation.ControlPoint.Positioner}
 
-                  * @apioption annotations.crookedLine.controlPointOptions.positioner
 
-                  */
 
-                 events: {}
 
-             },
 
-             /**
 
-              * @type {Object}
 
-              */
 
-             events: {},
 
-             /**
 
-              * The Z index of the annotation.
 
-              *
 
-              * @type {number}
 
-              * @default 6
 
-              */
 
-             zIndex: 6
 
-         },
 
-         /**
 
-          * Initialize the annotation.
 
-          *
 
-          * @param {Highcharts.Chart} - the chart
 
-          * @param {AnnotationOptions} - the user options for the annotation
 
-          */
 
-         init: function () {
 
-             this.linkPoints();
 
-             this.addControlPoints();
 
-             this.addShapes();
 
-             this.addLabels();
 
-             this.addClipPaths();
 
-             this.setLabelCollector();
 
-         },
 
-         getLabelsAndShapesOptions: function (baseOptions, newOptions) {
 
-             var mergedOptions = {};
 
-             ['labels', 'shapes'].forEach(function (name) {
 
-                 if (baseOptions[name]) {
 
-                     mergedOptions[name] = splat(newOptions[name]).map(
 
-                         function (basicOptions, i) {
 
-                             return merge(baseOptions[name][i], basicOptions);
 
-                         }
 
-                     );
 
-                 }
 
-             });
 
-             return mergedOptions;
 
-         },
 
-         addShapes: function () {
 
-             (this.options.shapes || []).forEach(function (shapeOptions, i) {
 
-                 var shape = this.initShape(shapeOptions, i);
 
-                 this.options.shapes[i] = shape.options;
 
-             }, this);
 
-         },
 
-         addLabels: function () {
 
-             (this.options.labels || []).forEach(function (labelOptions, i) {
 
-                 var label = this.initLabel(labelOptions, i);
 
-                 this.options.labels[i] = label.options;
 
-             }, this);
 
-         },
 
-         addClipPaths: function () {
 
-             this.setClipAxes();
 
-             if (this.clipXAxis && this.clipYAxis) {
 
-                 this.clipRect = this.chart.renderer.clipRect(
 
-                     this.getClipBox()
 
-                 );
 
-             }
 
-         },
 
-         setClipAxes: function () {
 
-             var xAxes = this.chart.xAxis,
 
-                 yAxes = this.chart.yAxis,
 
-                 linkedAxes = reduce(
 
-                     (this.options.labels || [])
 
-                         .concat(this.options.shapes || []),
 
-                     function (axes, labelOrShape) {
 
-                         return [
 
-                             xAxes[
 
-                                 labelOrShape &&
 
-                                 labelOrShape.point &&
 
-                                 labelOrShape.point.xAxis
 
-                             ] || axes[0],
 
-                             yAxes[
 
-                                 labelOrShape &&
 
-                                 labelOrShape.point &&
 
-                                 labelOrShape.point.yAxis
 
-                             ] || axes[1]
 
-                         ];
 
-                     },
 
-                     []
 
-                 );
 
-             this.clipXAxis = linkedAxes[0];
 
-             this.clipYAxis = linkedAxes[1];
 
-         },
 
-         getClipBox: function () {
 
-             return {
 
-                 x: this.clipXAxis.left,
 
-                 y: this.clipYAxis.top,
 
-                 width: this.clipXAxis.width,
 
-                 height: this.clipYAxis.height
 
-             };
 
-         },
 
-         setLabelCollector: function () {
 
-             var annotation = this;
 
-             annotation.labelCollector = function () {
 
-                 return annotation.labels.reduce(
 
-                     function (labels, label) {
 
-                         if (!label.options.allowOverlap) {
 
-                             labels.push(label.graphic);
 
-                         }
 
-                         return labels;
 
-                     },
 
-                     []
 
-                 );
 
-             };
 
-             annotation.chart.labelCollectors.push(
 
-                 annotation.labelCollector
 
-             );
 
-         },
 
-         /**
 
-          * Set an annotation options.
 
-          *
 
-          * @param {AnnotationOptions} - user options for an annotation
 
-          */
 
-         setOptions: function (userOptions) {
 
-             this.options = merge(this.defaultOptions, userOptions);
 
-         },
 
-         redraw: function (animation) {
 
-             this.linkPoints();
 
-             if (!this.graphic) {
 
-                 this.render();
 
-             }
 
-             if (this.clipRect) {
 
-                 this.clipRect.animate(this.getClipBox());
 
-             }
 
-             this.redrawItems(this.shapes, animation);
 
-             this.redrawItems(this.labels, animation);
 
-             controllableMixin.redraw.call(this, animation);
 
-         },
 
-         /**
 
-          * @param {Array<(Annotation.Label|Annotation.Shape)>} items
 
-          * @param {boolean} [animation]
 
-          */
 
-         redrawItems: function (items, animation) {
 
-             var i = items.length;
 
-             // needs a backward loop
 
-             // labels/shapes array might be modified
 
-             // due to destruction of the item
 
-             while (i--) {
 
-                 this.redrawItem(items[i], animation);
 
-             }
 
-         },
 
-         render: function () {
 
-             var renderer = this.chart.renderer;
 
-             this.graphic = renderer
 
-                 .g('annotation')
 
-                 .attr({
 
-                     zIndex: this.options.zIndex,
 
-                     visibility: this.options.visible ?
 
-                         'visible' :
 
-                         'hidden'
 
-                 })
 
-                 .add();
 
-             this.shapesGroup = renderer
 
-                 .g('annotation-shapes')
 
-                 .add(this.graphic)
 
-                 .clip(this.chart.plotBoxClip);
 
-             this.labelsGroup = renderer
 
-                 .g('annotation-labels')
 
-                 .attr({
 
-                     // hideOverlappingLabels requires translation
 
-                     translateX: 0,
 
-                     translateY: 0
 
-                 })
 
-                 .add(this.graphic);
 
-             if (this.clipRect) {
 
-                 this.graphic.clip(this.clipRect);
 
-             }
 
-             this.addEvents();
 
-             controllableMixin.render.call(this);
 
-         },
 
-         /**
 
-          * Set the annotation's visibility.
 
-          *
 
-          * @param {Boolean} [visible] - Whether to show or hide an annotation.
 
-          * If the param is omitted, the annotation's visibility is toggled.
 
-          */
 
-         setVisibility: function (visibility) {
 
-             var options = this.options,
 
-                 visible = pick(visibility, !options.visible);
 
-             this.graphic.attr(
 
-                 'visibility',
 
-                 visible ? 'visible' : 'hidden'
 
-             );
 
-             if (!visible) {
 
-                 this.setControlPointsVisibility(false);
 
-             }
 
-             options.visible = visible;
 
-         },
 
-         setControlPointsVisibility: function (visible) {
 
-             var setItemControlPointsVisibility = function (item) {
 
-                 item.setControlPointsVisibility(visible);
 
-             };
 
-             controllableMixin.setControlPointsVisibility.call(
 
-                 this,
 
-                 visible
 
-             );
 
-             this.shapes.forEach(setItemControlPointsVisibility);
 
-             this.labels.forEach(setItemControlPointsVisibility);
 
-         },
 
-         /**
 
-          * Destroy the annotation. This function does not touch the chart
 
-          * that the annotation belongs to (all annotations are kept in
 
-          * the chart.annotations array) - it is recommended to use
 
-          * {@link Highcharts.Chart#removeAnnotation} instead.
 
-          */
 
-         destroy: function () {
 
-             var chart = this.chart,
 
-                 destroyItem = function (item) {
 
-                     item.destroy();
 
-                 };
 
-             this.labels.forEach(destroyItem);
 
-             this.shapes.forEach(destroyItem);
 
-             this.clipXAxis = null;
 
-             this.clipYAxis = null;
 
-             erase(chart.labelCollectors, this.labelCollector);
 
-             eventEmitterMixin.destroy.call(this);
 
-             controllableMixin.destroy.call(this);
 
-             destroyObjectProperties(this, chart);
 
-         },
 
-         /**
 
-          * See {@link Highcharts.Annotation#destroy}.
 
-          */
 
-         remove: function () {
 
-             return this.destroy();
 
-         },
 
-         update: function (userOptions) {
 
-             var chart = this.chart,
 
-                 labelsAndShapes = this.getLabelsAndShapesOptions(
 
-                     this.userOptions,
 
-                     userOptions
 
-                 ),
 
-                 userOptionsIndex = chart.annotations.indexOf(this),
 
-                 options = H.merge(true, this.userOptions, userOptions);
 
-             options.labels = labelsAndShapes.labels;
 
-             options.shapes = labelsAndShapes.shapes;
 
-             this.destroy();
 
-             this.constructor(chart, options);
 
-             // Update options in chart options, used in exporting (#9767):
 
-             chart.options.annotations[userOptionsIndex] = options;
 
-             this.redraw();
 
-         },
 
-         /* *************************************************************
 
-          * ITEM SECTION
 
-          * Contains methods for handling a single item in an annotation
 
-          **************************************************************** */
 
-         /**
 
-          * Initialisation of a single shape
 
-          *
 
-          * @param {Object} shapeOptions - a confg object for a single shape
 
-          **/
 
-         initShape: function (shapeOptions, index) {
 
-             var options = merge(
 
-                     this.options.shapeOptions,
 
-                     {
 
-                         controlPointOptions: this.options.controlPointOptions
 
-                     },
 
-                     shapeOptions
 
-                 ),
 
-                 shape = new Annotation.shapesMap[options.type](
 
-                     this,
 
-                     options,
 
-                     index
 
-                 );
 
-             shape.itemType = 'shape';
 
-             this.shapes.push(shape);
 
-             return shape;
 
-         },
 
-         /**
 
-          * Initialisation of a single label
 
-          *
 
-          * @param {Object} labelOptions
 
-          **/
 
-         initLabel: function (labelOptions, index) {
 
-             var options = merge(
 
-                     this.options.labelOptions,
 
-                     {
 
-                         controlPointOptions: this.options.controlPointOptions
 
-                     },
 
-                     labelOptions
 
-                 ),
 
-                 label = new ControllableLabel(
 
-                     this,
 
-                     options,
 
-                     index
 
-                 );
 
-             label.itemType = 'label';
 
-             this.labels.push(label);
 
-             return label;
 
-         },
 
-         /**
 
-          * Redraw a single item.
 
-          *
 
-          * @param {Annotation.Label|Annotation.Shape} item
 
-          * @param {boolean} [animation]
 
-          */
 
-         redrawItem: function (item, animation) {
 
-             item.linkPoints();
 
-             if (!item.shouldBeDrawn()) {
 
-                 this.destroyItem(item);
 
-             } else {
 
-                 if (!item.graphic) {
 
-                     this.renderItem(item);
 
-                 }
 
-                 item.redraw(
 
-                     H.pick(animation, true) && item.graphic.placed
 
-                 );
 
-                 if (item.points.length) {
 
-                     this.adjustVisibility(item);
 
-                 }
 
-             }
 
-         },
 
-         /**
 
-          * Hide or show annotaiton attached to points.
 
-          *
 
-          * @param {Annotation.Label|Annotation.Shape} item
 
-          */
 
-         adjustVisibility: function (item) { // #9481
 
-             var hasVisiblePoints = false,
 
-                 label = item.graphic;
 
-             item.points.forEach(function (point) {
 
-                 if (
 
-                     point.series.visible !== false &&
 
-                     point.visible !== false
 
-                 ) {
 
-                     hasVisiblePoints = true;
 
-                 }
 
-             });
 
-             if (!hasVisiblePoints) {
 
-                 label.hide();
 
-             } else if (label.visibility === 'hidden') {
 
-                 label.show();
 
-             }
 
-         },
 
-         /**
 
-          * Destroy a single item.
 
-          *
 
-          * @param {Annotation.Label|Annotation.Shape} item
 
-          */
 
-         destroyItem: function (item) {
 
-             // erase from shapes or labels array
 
-             erase(this[item.itemType + 's'], item);
 
-             item.destroy();
 
-         },
 
-         /*
 
-          * @private
 
-          */
 
-         renderItem: function (item) {
 
-             item.render(
 
-                 item.itemType === 'label' ?
 
-                     this.labelsGroup :
 
-                     this.shapesGroup
 
-             );
 
-         }
 
-     }
 
- );
 
- /**
 
-  * An object uses for mapping between a shape type and a constructor.
 
-  * To add a new shape type extend this object with type name as a key
 
-  * and a constructor as its value.
 
-  **/
 
- Annotation.shapesMap = {
 
-     'rect': ControllableRect,
 
-     'circle': ControllableCircle,
 
-     'path': ControllablePath,
 
-     'image': ControllableImage
 
- };
 
- Annotation.types = {};
 
- Annotation.MockPoint = MockPoint;
 
- Annotation.ControlPoint = ControlPoint;
 
- H.extendAnnotation = function (
 
-     Constructor,
 
-     BaseConstructor,
 
-     prototype,
 
-     defaultOptions
 
- ) {
 
-     BaseConstructor = BaseConstructor || Annotation;
 
-     merge(
 
-         true,
 
-         Constructor.prototype,
 
-         BaseConstructor.prototype,
 
-         prototype
 
-     );
 
-     Constructor.prototype.defaultOptions = merge(
 
-         Constructor.prototype.defaultOptions,
 
-         defaultOptions || {}
 
-     );
 
- };
 
- /* *********************************************************************
 
-  *
 
-  * EXTENDING CHART PROTOTYPE
 
-  *
 
-  ******************************************************************** */
 
- // Let chart.update() work with annotations
 
- H.Chart.prototype.collectionsWithUpdate.push('annotations');
 
- H.extend(H.Chart.prototype, /** @lends Highcharts.Chart# */ {
 
-     initAnnotation: function (userOptions) {
 
-         var Constructor =
 
-             Annotation.types[userOptions.type] || Annotation,
 
-             options = H.merge(
 
-                 Constructor.prototype.defaultOptions,
 
-                 userOptions
 
-             ),
 
-             annotation = new Constructor(this, options);
 
-         this.annotations.push(annotation);
 
-         return annotation;
 
-     },
 
-     /**
 
-      * Add an annotation to the chart after render time.
 
-      *
 
-      * @param  {AnnotationOptions} options
 
-      *         The annotation options for the new, detailed annotation.
 
-      * @param {boolean} [redraw]
 
-      *
 
-      * @return {Highcharts.Annotation} - The newly generated annotation.
 
-      */
 
-     addAnnotation: function (userOptions, redraw) {
 
-         var annotation = this.initAnnotation(userOptions);
 
-         this.options.annotations.push(annotation.options);
 
-         if (pick(redraw, true)) {
 
-             annotation.redraw();
 
-         }
 
-         return annotation;
 
-     },
 
-     /**
 
-      * Remove an annotation from the chart.
 
-      *
 
-      * @param {String|Annotation} idOrAnnotation - The annotation's id or
 
-      *      direct annotation object.
 
-      */
 
-     removeAnnotation: function (idOrAnnotation) {
 
-         var annotations = this.annotations,
 
-             annotation = isString(idOrAnnotation) ? find(
 
-                 annotations,
 
-                 function (annotation) {
 
-                     return annotation.options.id === idOrAnnotation;
 
-                 }
 
-             ) : idOrAnnotation;
 
-         if (annotation) {
 
-             erase(this.options.annotations, annotation.options);
 
-             erase(annotations, annotation);
 
-             annotation.destroy();
 
-         }
 
-     },
 
-     drawAnnotations: function () {
 
-         this.plotBoxClip.attr(this.plotBox);
 
-         this.annotations.forEach(function (annotation) {
 
-             annotation.redraw();
 
-         });
 
-     }
 
- });
 
- H.Chart.prototype.callbacks.push(function (chart) {
 
-     chart.annotations = [];
 
-     if (!chart.options.annotations) {
 
-         chart.options.annotations = [];
 
-     }
 
-     chart.plotBoxClip = this.renderer.clipRect(this.plotBox);
 
-     chart.controlPointsGroup = chart.renderer
 
-         .g('control-points')
 
-         .attr({ zIndex: 99 })
 
-         .clip(chart.plotBoxClip)
 
-         .add();
 
-     chart.options.annotations.forEach(function (annotationOptions, i) {
 
-         var annotation = chart.initAnnotation(annotationOptions);
 
-         chart.options.annotations[i] = annotation.options;
 
-     });
 
-     chart.drawAnnotations();
 
-     addEvent(chart, 'redraw', chart.drawAnnotations);
 
-     addEvent(chart, 'destroy', function () {
 
-         chart.plotBoxClip.destroy();
 
-         chart.controlPointsGroup.destroy();
 
-     });
 
- });
 
 
  |