1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861 |
- /**
- *
- * Events generator for Stock tools
- *
- * (c) 2009-2021 Paweł Fus
- *
- * License: www.highcharts.com/license
- *
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
- *
- * */
- 'use strict';
- import H from '../Core/Globals.js';
- import NavigationBindings from '../Extensions/Annotations/NavigationBindings.js';
- import D from '../Core/DefaultOptions.js';
- var getOptions = D.getOptions, setOptions = D.setOptions;
- import Series from '../Core/Series/Series.js';
- import U from '../Core/Utilities.js';
- import palette from '../Core/Color/Palette.js';
- var correctFloat = U.correctFloat, defined = U.defined, extend = U.extend, fireEvent = U.fireEvent, isNumber = U.isNumber, merge = U.merge, pick = U.pick, uniqueKey = U.uniqueKey;
- var bindingsUtils = NavigationBindings.prototype.utils, PREFIX = 'highcharts-';
- /* eslint-disable no-invalid-this, valid-jsdoc */
- /**
- * Generates function which will add a flag series using modal in GUI.
- * Method fires an event "showPopup" with config:
- * `{type, options, callback}`.
- *
- * Example: NavigationBindings.utils.addFlagFromForm('url(...)') - will
- * generate function that shows modal in GUI.
- *
- * @private
- * @function bindingsUtils.addFlagFromForm
- *
- * @param {Highcharts.FlagsShapeValue} type
- * Type of flag series, e.g. "squarepin"
- *
- * @return {Function}
- * Callback to be used in `start` callback
- */
- bindingsUtils.addFlagFromForm = function (type) {
- return function (e) {
- var navigation = this, chart = navigation.chart, toolbar = chart.stockTools, getFieldType = bindingsUtils.getFieldType, point = bindingsUtils.attractToPoint(e, chart), pointConfig, seriesOptions;
- if (!point) {
- return;
- }
- pointConfig = {
- x: point.x,
- y: point.y
- };
- seriesOptions = {
- type: 'flags',
- onSeries: point.series.id,
- shape: type,
- data: [pointConfig],
- xAxis: point.xAxis,
- yAxis: point.yAxis,
- point: {
- events: {
- click: function () {
- var point = this, options = point.options;
- fireEvent(navigation, 'showPopup', {
- point: point,
- formType: 'annotation-toolbar',
- options: {
- langKey: 'flags',
- type: 'flags',
- title: [
- options.title,
- getFieldType(options.title)
- ],
- name: [
- options.name,
- getFieldType(options.name)
- ]
- },
- onSubmit: function (updated) {
- if (updated.actionType === 'remove') {
- point.remove();
- }
- else {
- point.update(navigation.fieldsToOptions(updated.fields, {}));
- }
- }
- });
- }
- }
- }
- };
- if (!toolbar || !toolbar.guiEnabled) {
- chart.addSeries(seriesOptions);
- }
- fireEvent(navigation, 'showPopup', {
- formType: 'flag',
- // Enabled options:
- options: {
- langKey: 'flags',
- type: 'flags',
- title: ['A', getFieldType('A')],
- name: ['Flag A', getFieldType('Flag A')]
- },
- // Callback on submit:
- onSubmit: function (data) {
- navigation.fieldsToOptions(data.fields, seriesOptions.data[0]);
- chart.addSeries(seriesOptions);
- }
- });
- };
- };
- bindingsUtils.manageIndicators = function (data) {
- var navigation = this, chart = navigation.chart, seriesConfig = {
- linkedTo: data.linkedTo,
- type: data.type
- }, indicatorsWithVolume = [
- 'ad',
- 'cmf',
- 'klinger',
- 'mfi',
- 'obv',
- 'vbp',
- 'vwap'
- ], indicatorsWithAxes = [
- 'ad',
- 'atr',
- 'cci',
- 'cmf',
- 'disparityindex',
- 'cmo',
- 'dmi',
- 'macd',
- 'mfi',
- 'roc',
- 'rsi',
- 'ao',
- 'aroon',
- 'aroonoscillator',
- 'trix',
- 'apo',
- 'dpo',
- 'ppo',
- 'natr',
- 'obv',
- 'williamsr',
- 'stochastic',
- 'slowstochastic',
- 'linearRegression',
- 'linearRegressionSlope',
- 'linearRegressionIntercept',
- 'linearRegressionAngle',
- 'klinger'
- ], yAxis, parentSeries, defaultOptions, series;
- if (data.actionType === 'edit') {
- navigation.fieldsToOptions(data.fields, seriesConfig);
- series = chart.get(data.seriesId);
- if (series) {
- series.update(seriesConfig, false);
- }
- }
- else if (data.actionType === 'remove') {
- series = chart.get(data.seriesId);
- if (series) {
- yAxis = series.yAxis;
- if (series.linkedSeries) {
- series.linkedSeries.forEach(function (linkedSeries) {
- linkedSeries.remove(false);
- });
- }
- series.remove(false);
- if (indicatorsWithAxes.indexOf(series.type) >= 0) {
- var removedYAxisHeight = yAxis.options.height;
- yAxis.remove(false);
- navigation.resizeYAxes(removedYAxisHeight);
- }
- }
- }
- else {
- seriesConfig.id = uniqueKey();
- navigation.fieldsToOptions(data.fields, seriesConfig);
- parentSeries = chart.get(seriesConfig.linkedTo);
- defaultOptions = getOptions().plotOptions;
- // Make sure that indicator uses the SUM approx if SUM approx is used
- // by parent series (#13950).
- if (typeof parentSeries !== 'undefined' &&
- parentSeries instanceof Series &&
- parentSeries.getDGApproximation() === 'sum' &&
- // If indicator has defined approx type, use it (e.g. "ranges")
- !defined(defaultOptions && defaultOptions[seriesConfig.type] &&
- defaultOptions.dataGrouping &&
- defaultOptions.dataGrouping.approximation)) {
- seriesConfig.dataGrouping = {
- approximation: 'sum'
- };
- }
- if (indicatorsWithAxes.indexOf(data.type) >= 0) {
- yAxis = chart.addAxis({
- id: uniqueKey(),
- offset: 0,
- opposite: true,
- title: {
- text: ''
- },
- tickPixelInterval: 40,
- showLastLabel: false,
- labels: {
- align: 'left',
- y: -2
- }
- }, false, false);
- seriesConfig.yAxis = yAxis.options.id;
- navigation.resizeYAxes();
- }
- else {
- seriesConfig.yAxis = chart.get(data.linkedTo).options.yAxis;
- }
- if (indicatorsWithVolume.indexOf(data.type) >= 0) {
- seriesConfig.params.volumeSeriesID = chart.series.filter(function (series) {
- return series.options.type === 'column';
- })[0].options.id;
- }
- chart.addSeries(seriesConfig, false);
- }
- fireEvent(navigation, 'deselectButton', {
- button: navigation.selectedButtonElement
- });
- chart.redraw();
- };
- /**
- * Update height for an annotation. Height is calculated as a difference
- * between last point in `typeOptions` and current position. It's a value,
- * not pixels height.
- *
- * @private
- * @function bindingsUtils.updateHeight
- *
- * @param {Highcharts.PointerEventObject} e
- * normalized browser event
- *
- * @param {Highcharts.Annotation} annotation
- * Annotation to be updated
- *
- * @return {void}
- */
- bindingsUtils.updateHeight = function (e, annotation) {
- var coordsY = this.utils.getAssignedAxis(this.chart.pointer.getCoordinates(e).yAxis);
- if (coordsY) {
- annotation.update({
- typeOptions: {
- height: coordsY.value -
- annotation.options.typeOptions.points[1].y
- }
- });
- }
- };
- // @todo
- // Consider using getHoverData(), but always kdTree (columns?)
- bindingsUtils.attractToPoint = function (e, chart) {
- var coords = chart.pointer.getCoordinates(e), coordsX, coordsY, distX = Number.MAX_VALUE, closestPoint, x, y;
- if (chart.navigationBindings) {
- coordsX = chart.navigationBindings.utils.getAssignedAxis(coords.xAxis);
- coordsY = chart.navigationBindings.utils.getAssignedAxis(coords.yAxis);
- }
- // Exit if clicked out of axes area.
- if (!coordsX || !coordsY) {
- return;
- }
- x = coordsX.value;
- y = coordsY.value;
- // Search by 'x' but only in yAxis' series.
- coordsY.axis.series.forEach(function (series) {
- if (series.points) {
- series.points.forEach(function (point) {
- if (point && distX > Math.abs(point.x - x)) {
- distX = Math.abs(point.x - x);
- closestPoint = point;
- }
- });
- }
- });
- if (closestPoint && closestPoint.x && closestPoint.y) {
- return {
- x: closestPoint.x,
- y: closestPoint.y,
- below: y < closestPoint.y,
- series: closestPoint.series,
- xAxis: closestPoint.series.xAxis.options.index || 0,
- yAxis: closestPoint.series.yAxis.options.index || 0
- };
- }
- };
- /**
- * Shorthand to check if given yAxis comes from navigator.
- *
- * @private
- * @function bindingsUtils.isNotNavigatorYAxis
- *
- * @param {Highcharts.Axis} axis
- * Axis to check.
- *
- * @return {boolean}
- * True, if axis comes from navigator.
- */
- bindingsUtils.isNotNavigatorYAxis = function (axis) {
- return axis.userOptions.className !== PREFIX + 'navigator-yaxis';
- };
- /**
- * Check if any of the price indicators are enabled.
- * @private
- * @function bindingsUtils.isLastPriceEnabled
- *
- * @param {array} series
- * Array of series.
- *
- * @return {boolean}
- * Tells which indicator is enabled.
- */
- bindingsUtils.isPriceIndicatorEnabled = function (series) {
- return series.some(function (s) { return s.lastVisiblePrice || s.lastPrice; });
- };
- /**
- * Update each point after specified index, most of the annotations use
- * this. For example crooked line: logic behind updating each point is the
- * same, only index changes when adding an annotation.
- *
- * Example: NavigationBindings.utils.updateNthPoint(1) - will generate
- * function that updates all consecutive points except point with index=0.
- *
- * @private
- * @function bindingsUtils.updateNthPoint
- *
- * @param {number} startIndex
- * Index from each point should udpated
- *
- * @return {Function}
- * Callback to be used in steps array
- */
- bindingsUtils.updateNthPoint = function (startIndex) {
- return function (e, annotation) {
- var options = annotation.options.typeOptions, coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis);
- if (coordsX && coordsY) {
- options.points.forEach(function (point, index) {
- if (index >= startIndex) {
- point.x = coordsX.value;
- point.y = coordsY.value;
- }
- });
- annotation.update({
- typeOptions: {
- points: options.points
- }
- });
- }
- };
- };
- // Extends NavigationBindigs to support indicators and resizers:
- extend(NavigationBindings.prototype, {
- /* eslint-disable valid-jsdoc */
- /**
- * Get current positions for all yAxes. If new axis does not have position,
- * returned is default height and last available top place.
- *
- * @private
- * @function Highcharts.NavigationBindings#getYAxisPositions
- *
- * @param {Array<Highcharts.Axis>} yAxes
- * Array of yAxes available in the chart.
- *
- * @param {number} plotHeight
- * Available height in the chart.
- *
- * @param {number} defaultHeight
- * Default height in percents.
- *
- * @param {string} removedYAxisHeight
- * Height of the removed yAxis in percents.
- *
- * @return {Highcharts.YAxisPositions}
- * An object containing an array of calculated positions
- * in percentages. Format: `{top: Number, height: Number}`
- * and maximum value of top + height of axes.
- */
- getYAxisPositions: function (yAxes, plotHeight, defaultHeight, removedYAxisHeight) {
- var positions, allAxesHeight = 0, previousAxisHeight, removedHeight;
- /** @private */
- function isPercentage(prop) {
- return defined(prop) && !isNumber(prop) && prop.match('%');
- }
- if (removedYAxisHeight) {
- removedHeight = correctFloat((parseFloat(removedYAxisHeight) / 100));
- }
- positions = yAxes.map(function (yAxis, index) {
- var height = correctFloat(isPercentage(yAxis.options.height) ?
- parseFloat(yAxis.options.height) / 100 :
- yAxis.height / plotHeight), top = correctFloat(isPercentage(yAxis.options.top) ?
- parseFloat(yAxis.options.top) / 100 :
- (yAxis.top - yAxis.chart.plotTop) / plotHeight);
- // New axis' height is NaN so we can check if
- // the axis is newly created this way
- if (!removedHeight) {
- if (!isNumber(height)) {
- // Check if the previous axis is the
- // indicator axis (every indicator inherits from sma)
- height = yAxes[index - 1].series.every(function (s) { return s.is('sma'); }) ?
- previousAxisHeight : defaultHeight / 100;
- }
- if (!isNumber(top)) {
- top = allAxesHeight;
- }
- previousAxisHeight = height;
- allAxesHeight = correctFloat(Math.max(allAxesHeight, (top || 0) + (height || 0)));
- }
- else {
- if (top <= allAxesHeight) {
- allAxesHeight = correctFloat(Math.max(allAxesHeight, (top || 0) + (height || 0)));
- }
- else {
- top = correctFloat(top - removedHeight);
- allAxesHeight = correctFloat(allAxesHeight + height);
- }
- }
- return {
- height: height * 100,
- top: top * 100
- };
- });
- return { positions: positions, allAxesHeight: allAxesHeight };
- },
- /**
- * Get current resize options for each yAxis. Note that each resize is
- * linked to the next axis, except the last one which shouldn't affect
- * axes in the navigator. Because indicator can be removed with it's yAxis
- * in the middle of yAxis array, we need to bind closest yAxes back.
- *
- * @private
- * @function Highcharts.NavigationBindings#getYAxisResizers
- *
- * @param {Array<Highcharts.Axis>} yAxes
- * Array of yAxes available in the chart
- *
- * @return {Array<object>}
- * An array of resizer options.
- * Format: `{enabled: Boolean, controlledAxis: { next: [String]}}`
- */
- getYAxisResizers: function (yAxes) {
- var resizers = [];
- yAxes.forEach(function (_yAxis, index) {
- var nextYAxis = yAxes[index + 1];
- // We have next axis, bind them:
- if (nextYAxis) {
- resizers[index] = {
- enabled: true,
- controlledAxis: {
- next: [
- pick(nextYAxis.options.id, nextYAxis.options.index)
- ]
- }
- };
- }
- else {
- // Remove binding:
- resizers[index] = {
- enabled: false
- };
- }
- });
- return resizers;
- },
- /**
- * Resize all yAxes (except navigator) to fit the plotting height. Method
- * checks if new axis is added, if the new axis will fit under previous
- * axes it is placed there. If not, current plot area is scaled
- * to make room for new axis.
- *
- * If axis is removed, the current plot area streaches to fit into 100%
- * of the plot area.
- *
- * @private
- * @function Highcharts.NavigationBindings#resizeYAxes
- * @param {string} [removedYAxisHeight]
- *
- *
- */
- resizeYAxes: function (removedYAxisHeight) {
- // The height of the new axis before rescalling. In %, but as a number.
- var defaultHeight = 20;
- var chart = this.chart,
- // Only non-navigator axes
- yAxes = chart.yAxis.filter(bindingsUtils.isNotNavigatorYAxis), plotHeight = chart.plotHeight,
- // Gather current heights (in %)
- _a = this.getYAxisPositions(yAxes, plotHeight, defaultHeight, removedYAxisHeight), positions = _a.positions, allAxesHeight = _a.allAxesHeight, resizers = this.getYAxisResizers(yAxes);
- // check if the axis is being either added or removed and
- // if the new indicator axis will fit under existing axes.
- // if so, there is no need to scale them.
- if (!removedYAxisHeight &&
- allAxesHeight <= correctFloat(0.8 + defaultHeight / 100)) {
- positions[positions.length - 1] = {
- height: defaultHeight,
- top: correctFloat(allAxesHeight * 100 - defaultHeight)
- };
- }
- else {
- positions.forEach(function (position) {
- position.height = (position.height / (allAxesHeight * 100)) * 100;
- position.top = (position.top / (allAxesHeight * 100)) * 100;
- });
- }
- positions.forEach(function (position, index) {
- yAxes[index].update({
- height: position.height + '%',
- top: position.top + '%',
- resize: resizers[index],
- offset: 0
- }, false);
- });
- },
- /**
- * Utility to modify calculated positions according to the remaining/needed
- * space. Later, these positions are used in `yAxis.update({ top, height })`
- *
- * @private
- * @function Highcharts.NavigationBindings#recalculateYAxisPositions
- * @param {Array<Highcharts.Dictionary<number>>} positions
- * Default positions of all yAxes.
- * @param {number} changedSpace
- * How much space should be added or removed.
- * @param {boolean} modifyHeight
- * Update only `top` or both `top` and `height`.
- * @param {number} adder
- * `-1` or `1`, to determine whether we should add or remove space.
- *
- * @return {Array<object>}
- * Modified positions,
- */
- recalculateYAxisPositions: function (positions, changedSpace, modifyHeight, adder) {
- positions.forEach(function (position, index) {
- var prevPosition = positions[index - 1];
- position.top = !prevPosition ? 0 :
- correctFloat(prevPosition.height + prevPosition.top);
- if (modifyHeight) {
- position.height = correctFloat(position.height + adder * changedSpace);
- }
- });
- return positions;
- }
- /* eslint-enable valid-jsdoc */
- });
- /**
- * @type {Highcharts.Dictionary<Highcharts.NavigationBindingsOptionsObject>}
- * @since 7.0.0
- * @optionparent navigation.bindings
- */
- var stockToolsBindings = {
- // Line type annotations:
- /**
- * A segment annotation bindings. Includes `start` and one event in `steps`
- * array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-segment", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
- */
- segment: {
- /** @ignore-option */
- className: 'highcharts-segment',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis), navigation = this.chart.options.navigation, options;
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- options = merge({
- langKey: 'segment',
- type: 'crookedLine',
- typeOptions: {
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [{
- x: coordsX.value,
- y: coordsY.value
- }, {
- x: coordsX.value,
- y: coordsY.value
- }]
- }
- }, navigation.annotationsOptions, navigation.bindings.segment.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1)
- ]
- },
- /**
- * A segment with an arrow annotation bindings. Includes `start` and one
- * event in `steps` array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-arrow-segment", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
- */
- arrowSegment: {
- /** @ignore-option */
- className: 'highcharts-arrow-segment',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis), navigation = this.chart.options.navigation, options;
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- options = merge({
- langKey: 'arrowSegment',
- type: 'crookedLine',
- typeOptions: {
- line: {
- markerEnd: 'arrow'
- },
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [{
- x: coordsX.value,
- y: coordsY.value
- }, {
- x: coordsX.value,
- y: coordsY.value
- }]
- }
- }, navigation.annotationsOptions, navigation.bindings.arrowSegment.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1)
- ]
- },
- /**
- * A ray annotation bindings. Includes `start` and one event in `steps`
- * array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-ray", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
- */
- ray: {
- /** @ignore-option */
- className: 'highcharts-ray',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis), navigation = this.chart.options.navigation, options;
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- options = merge({
- langKey: 'ray',
- type: 'infinityLine',
- typeOptions: {
- type: 'ray',
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [{
- x: coordsX.value,
- y: coordsY.value
- }, {
- x: coordsX.value,
- y: coordsY.value
- }]
- }
- }, navigation.annotationsOptions, navigation.bindings.ray.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1)
- ]
- },
- /**
- * A ray with an arrow annotation bindings. Includes `start` and one event
- * in `steps` array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-arrow-ray", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
- */
- arrowRay: {
- /** @ignore-option */
- className: 'highcharts-arrow-ray',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis), navigation = this.chart.options.navigation, options;
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- options = merge({
- langKey: 'arrowRay',
- type: 'infinityLine',
- typeOptions: {
- type: 'ray',
- line: {
- markerEnd: 'arrow'
- },
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [{
- x: coordsX.value,
- y: coordsY.value
- }, {
- x: coordsX.value,
- y: coordsY.value
- }]
- }
- }, navigation.annotationsOptions, navigation.bindings.arrowRay.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1)
- ]
- },
- /**
- * A line annotation. Includes `start` and one event in `steps` array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-infinity-line", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
- */
- infinityLine: {
- /** @ignore-option */
- className: 'highcharts-infinity-line',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis), navigation = this.chart.options.navigation, options;
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- options = merge({
- langKey: 'infinityLine',
- type: 'infinityLine',
- typeOptions: {
- type: 'line',
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [{
- x: coordsX.value,
- y: coordsY.value
- }, {
- x: coordsX.value,
- y: coordsY.value
- }]
- }
- }, navigation.annotationsOptions, navigation.bindings.infinityLine.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1)
- ]
- },
- /**
- * A line with arrow annotation. Includes `start` and one event in `steps`
- * array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-arrow-infinity-line", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
- */
- arrowInfinityLine: {
- /** @ignore-option */
- className: 'highcharts-arrow-infinity-line',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis), navigation = this.chart.options.navigation, options;
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- options = merge({
- langKey: 'arrowInfinityLine',
- type: 'infinityLine',
- typeOptions: {
- type: 'line',
- line: {
- markerEnd: 'arrow'
- },
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [{
- x: coordsX.value,
- y: coordsY.value
- }, {
- x: coordsX.value,
- y: coordsY.value
- }]
- }
- }, navigation.annotationsOptions, navigation.bindings.arrowInfinityLine.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1)
- ]
- },
- /**
- * A horizontal line annotation. Includes `start` event.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-horizontal-line", "start": function() {}, "annotationsOptions": {}}
- */
- horizontalLine: {
- /** @ignore-option */
- className: 'highcharts-horizontal-line',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis), navigation = this.chart.options.navigation, options;
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- options = merge({
- langKey: 'horizontalLine',
- type: 'infinityLine',
- draggable: 'y',
- typeOptions: {
- type: 'horizontalLine',
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [{
- x: coordsX.value,
- y: coordsY.value
- }]
- }
- }, navigation.annotationsOptions, navigation.bindings.horizontalLine.annotationsOptions);
- this.chart.addAnnotation(options);
- }
- },
- /**
- * A vertical line annotation. Includes `start` event.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-vertical-line", "start": function() {}, "annotationsOptions": {}}
- */
- verticalLine: {
- /** @ignore-option */
- className: 'highcharts-vertical-line',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis), navigation = this.chart.options.navigation, options;
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- options = merge({
- langKey: 'verticalLine',
- type: 'infinityLine',
- draggable: 'x',
- typeOptions: {
- type: 'verticalLine',
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [{
- x: coordsX.value,
- y: coordsY.value
- }]
- }
- }, navigation.annotationsOptions, navigation.bindings.verticalLine.annotationsOptions);
- this.chart.addAnnotation(options);
- }
- },
- /**
- * Crooked line (three points) annotation bindings. Includes `start` and two
- * events in `steps` (for second and third points in crooked line) array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-crooked3", "start": function() {}, "steps": [function() {}, function() {}], "annotationsOptions": {}}
- */
- // Crooked Line type annotations:
- crooked3: {
- /** @ignore-option */
- className: 'highcharts-crooked3',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis);
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- var x = coordsX.value, y = coordsY.value, navigation = this.chart.options.navigation, options = merge({
- langKey: 'crooked3',
- type: 'crookedLine',
- typeOptions: {
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [
- { x: x, y: y },
- { x: x, y: y },
- { x: x, y: y }
- ]
- }
- }, navigation.annotationsOptions, navigation.bindings.crooked3.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1),
- bindingsUtils.updateNthPoint(2)
- ]
- },
- /**
- * Crooked line (five points) annotation bindings. Includes `start` and four
- * events in `steps` (for all consequent points in crooked line) array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-crooked3", "start": function() {}, "steps": [function() {}, function() {}, function() {}, function() {}], "annotationsOptions": {}}
- */
- crooked5: {
- /** @ignore-option */
- className: 'highcharts-crooked5',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis);
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- var x = coordsX.value, y = coordsY.value, navigation = this.chart.options.navigation, options = merge({
- langKey: 'crookedLine',
- type: 'crookedLine',
- typeOptions: {
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [
- { x: x, y: y },
- { x: x, y: y },
- { x: x, y: y },
- { x: x, y: y },
- { x: x, y: y }
- ]
- }
- }, navigation.annotationsOptions, navigation.bindings.crooked5.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1),
- bindingsUtils.updateNthPoint(2),
- bindingsUtils.updateNthPoint(3),
- bindingsUtils.updateNthPoint(4)
- ]
- },
- /**
- * Elliott wave (three points) annotation bindings. Includes `start` and two
- * events in `steps` (for second and third points) array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-elliott3", "start": function() {}, "steps": [function() {}, function() {}], "annotationsOptions": {}}
- */
- elliott3: {
- /** @ignore-option */
- className: 'highcharts-elliott3',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis);
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- var x = coordsX.value, y = coordsY.value, navigation = this.chart.options.navigation, options = merge({
- langKey: 'elliott3',
- type: 'elliottWave',
- typeOptions: {
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [
- { x: x, y: y },
- { x: x, y: y },
- { x: x, y: y },
- { x: x, y: y }
- ]
- },
- labelOptions: {
- style: {
- color: palette.neutralColor60
- }
- }
- }, navigation.annotationsOptions, navigation.bindings.elliott3.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1),
- bindingsUtils.updateNthPoint(2),
- bindingsUtils.updateNthPoint(3)
- ]
- },
- /**
- * Elliott wave (five points) annotation bindings. Includes `start` and four
- * event in `steps` (for all consequent points in Elliott wave) array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-elliott3", "start": function() {}, "steps": [function() {}, function() {}, function() {}, function() {}], "annotationsOptions": {}}
- */
- elliott5: {
- /** @ignore-option */
- className: 'highcharts-elliott5',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis);
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- var x = coordsX.value, y = coordsY.value, navigation = this.chart.options.navigation, options = merge({
- langKey: 'elliott5',
- type: 'elliottWave',
- typeOptions: {
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [
- { x: x, y: y },
- { x: x, y: y },
- { x: x, y: y },
- { x: x, y: y },
- { x: x, y: y },
- { x: x, y: y }
- ]
- },
- labelOptions: {
- style: {
- color: palette.neutralColor60
- }
- }
- }, navigation.annotationsOptions, navigation.bindings.elliott5.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1),
- bindingsUtils.updateNthPoint(2),
- bindingsUtils.updateNthPoint(3),
- bindingsUtils.updateNthPoint(4),
- bindingsUtils.updateNthPoint(5)
- ]
- },
- /**
- * A measure (x-dimension) annotation bindings. Includes `start` and one
- * event in `steps` array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-measure-x", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
- */
- measureX: {
- /** @ignore-option */
- className: 'highcharts-measure-x',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis);
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- var x = coordsX.value, y = coordsY.value, navigation = this.chart.options.navigation, options = merge({
- langKey: 'measure',
- type: 'measure',
- typeOptions: {
- selectType: 'x',
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- point: { x: x, y: y },
- crosshairX: {
- strokeWidth: 1,
- stroke: palette.neutralColor100
- },
- crosshairY: {
- enabled: false,
- strokeWidth: 0,
- stroke: palette.neutralColor100
- },
- background: {
- width: 0,
- height: 0,
- strokeWidth: 0,
- stroke: palette.backgroundColor
- }
- },
- labelOptions: {
- style: {
- color: palette.neutralColor60
- }
- }
- }, navigation.annotationsOptions, navigation.bindings.measureX.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateRectSize
- ]
- },
- /**
- * A measure (y-dimension) annotation bindings. Includes `start` and one
- * event in `steps` array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-measure-y", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
- */
- measureY: {
- /** @ignore-option */
- className: 'highcharts-measure-y',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis);
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- var x = coordsX.value, y = coordsY.value, navigation = this.chart.options.navigation, options = merge({
- langKey: 'measure',
- type: 'measure',
- typeOptions: {
- selectType: 'y',
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- point: { x: x, y: y },
- crosshairX: {
- enabled: false,
- strokeWidth: 0,
- stroke: palette.neutralColor100
- },
- crosshairY: {
- strokeWidth: 1,
- stroke: palette.neutralColor100
- },
- background: {
- width: 0,
- height: 0,
- strokeWidth: 0,
- stroke: palette.backgroundColor
- }
- },
- labelOptions: {
- style: {
- color: palette.neutralColor60
- }
- }
- }, navigation.annotationsOptions, navigation.bindings.measureY.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateRectSize
- ]
- },
- /**
- * A measure (xy-dimension) annotation bindings. Includes `start` and one
- * event in `steps` array.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-measure-xy", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
- */
- measureXY: {
- /** @ignore-option */
- className: 'highcharts-measure-xy',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis);
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- var x = coordsX.value, y = coordsY.value, navigation = this.chart.options.navigation, options = merge({
- langKey: 'measure',
- type: 'measure',
- typeOptions: {
- selectType: 'xy',
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- point: { x: x, y: y },
- background: {
- width: 0,
- height: 0,
- strokeWidth: 10
- },
- crosshairX: {
- strokeWidth: 1,
- stroke: palette.neutralColor100
- },
- crosshairY: {
- strokeWidth: 1,
- stroke: palette.neutralColor100
- }
- },
- labelOptions: {
- style: {
- color: palette.neutralColor60
- }
- }
- }, navigation.annotationsOptions, navigation.bindings.measureXY.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateRectSize
- ]
- },
- // Advanced type annotations:
- /**
- * A fibonacci annotation bindings. Includes `start` and two events in
- * `steps` array (updates second point, then height).
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-fibonacci", "start": function() {}, "steps": [function() {}, function() {}], "annotationsOptions": {}}
- */
- fibonacci: {
- /** @ignore-option */
- className: 'highcharts-fibonacci',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis);
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- var x = coordsX.value, y = coordsY.value, navigation = this.chart.options.navigation, options = merge({
- langKey: 'fibonacci',
- type: 'fibonacci',
- typeOptions: {
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [
- { x: x, y: y },
- { x: x, y: y }
- ]
- },
- labelOptions: {
- style: {
- color: palette.neutralColor60
- }
- }
- }, navigation.annotationsOptions, navigation.bindings.fibonacci.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1),
- bindingsUtils.updateHeight
- ]
- },
- /**
- * A parallel channel (tunnel) annotation bindings. Includes `start` and
- * two events in `steps` array (updates second point, then height).
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-parallel-channel", "start": function() {}, "steps": [function() {}, function() {}], "annotationsOptions": {}}
- */
- parallelChannel: {
- /** @ignore-option */
- className: 'highcharts-parallel-channel',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis);
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- var x = coordsX.value, y = coordsY.value, navigation = this.chart.options.navigation, options = merge({
- langKey: 'parallelChannel',
- type: 'tunnel',
- typeOptions: {
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [
- { x: x, y: y },
- { x: x, y: y }
- ]
- }
- }, navigation.annotationsOptions, navigation.bindings.parallelChannel.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1),
- bindingsUtils.updateHeight
- ]
- },
- /**
- * An Andrew's pitchfork annotation bindings. Includes `start` and two
- * events in `steps` array (sets second and third control points).
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-pitchfork", "start": function() {}, "steps": [function() {}, function() {}], "annotationsOptions": {}}
- */
- pitchfork: {
- /** @ignore-option */
- className: 'highcharts-pitchfork',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var coords = this.chart.pointer.getCoordinates(e), coordsX = this.utils.getAssignedAxis(coords.xAxis), coordsY = this.utils.getAssignedAxis(coords.yAxis);
- // Exit if clicked out of axes area
- if (!coordsX || !coordsY) {
- return;
- }
- var x = coordsX.value, y = coordsY.value, navigation = this.chart.options.navigation, options = merge({
- langKey: 'pitchfork',
- type: 'pitchfork',
- typeOptions: {
- xAxis: coordsX.axis.options.index,
- yAxis: coordsY.axis.options.index,
- points: [{
- x: coordsX.value,
- y: coordsY.value,
- controlPoint: {
- style: {
- fill: palette.negativeColor
- }
- }
- }, { x: x, y: y },
- { x: x, y: y }],
- innerBackground: {
- fill: 'rgba(100, 170, 255, 0.8)'
- }
- },
- shapeOptions: {
- strokeWidth: 2
- }
- }, navigation.annotationsOptions, navigation.bindings.pitchfork.annotationsOptions);
- return this.chart.addAnnotation(options);
- },
- /** @ignore-option */
- steps: [
- bindingsUtils.updateNthPoint(1),
- bindingsUtils.updateNthPoint(2)
- ]
- },
- // Labels with arrow and auto increments
- /**
- * A vertical counter annotation bindings. Includes `start` event. On click,
- * finds the closest point and marks it with a numeric annotation -
- * incrementing counter on each add.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-vertical-counter", "start": function() {}, "annotationsOptions": {}}
- */
- verticalCounter: {
- /** @ignore-option */
- className: 'highcharts-vertical-counter',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var closestPoint = bindingsUtils.attractToPoint(e, this.chart), navigation = this.chart.options.navigation, options, annotation;
- // Exit if clicked out of axes area
- if (!closestPoint) {
- return;
- }
- this.verticalCounter = this.verticalCounter || 0;
- options = merge({
- langKey: 'verticalCounter',
- type: 'verticalLine',
- typeOptions: {
- point: {
- x: closestPoint.x,
- y: closestPoint.y,
- xAxis: closestPoint.xAxis,
- yAxis: closestPoint.yAxis
- },
- label: {
- offset: closestPoint.below ? 40 : -40,
- text: this.verticalCounter.toString()
- }
- },
- labelOptions: {
- style: {
- color: palette.neutralColor60,
- fontSize: '11px'
- }
- },
- shapeOptions: {
- stroke: 'rgba(0, 0, 0, 0.75)',
- strokeWidth: 1
- }
- }, navigation.annotationsOptions, navigation.bindings.verticalCounter.annotationsOptions);
- annotation = this.chart.addAnnotation(options);
- this.verticalCounter++;
- annotation.options.events.click.call(annotation, {});
- }
- },
- /**
- * A vertical arrow annotation bindings. Includes `start` event. On click,
- * finds the closest point and marks it with an arrow and a label with
- * value.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-vertical-label", "start": function() {}, "annotationsOptions": {}}
- */
- verticalLabel: {
- /** @ignore-option */
- className: 'highcharts-vertical-label',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var closestPoint = bindingsUtils.attractToPoint(e, this.chart), navigation = this.chart.options.navigation, options, annotation;
- // Exit if clicked out of axes area
- if (!closestPoint) {
- return;
- }
- options = merge({
- langKey: 'verticalLabel',
- type: 'verticalLine',
- typeOptions: {
- point: {
- x: closestPoint.x,
- y: closestPoint.y,
- xAxis: closestPoint.xAxis,
- yAxis: closestPoint.yAxis
- },
- label: {
- offset: closestPoint.below ? 40 : -40
- }
- },
- labelOptions: {
- style: {
- color: palette.neutralColor60,
- fontSize: '11px'
- }
- },
- shapeOptions: {
- stroke: 'rgba(0, 0, 0, 0.75)',
- strokeWidth: 1
- }
- }, navigation.annotationsOptions, navigation.bindings.verticalLabel.annotationsOptions);
- annotation = this.chart.addAnnotation(options);
- annotation.options.events.click.call(annotation, {});
- }
- },
- /**
- * A vertical arrow annotation bindings. Includes `start` event. On click,
- * finds the closest point and marks it with an arrow.
- * `${palette.positiveColor}` is the color of the arrow when
- * pointing from above and `${palette.negativeColor}`
- * when pointing from below the point.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-vertical-arrow", "start": function() {}, "annotationsOptions": {}}
- */
- verticalArrow: {
- /** @ignore-option */
- className: 'highcharts-vertical-arrow',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- start: function (e) {
- var closestPoint = bindingsUtils.attractToPoint(e, this.chart), navigation = this.chart.options.navigation, options, annotation;
- // Exit if clicked out of axes area
- if (!closestPoint) {
- return;
- }
- options = merge({
- langKey: 'verticalArrow',
- type: 'verticalLine',
- typeOptions: {
- point: {
- x: closestPoint.x,
- y: closestPoint.y,
- xAxis: closestPoint.xAxis,
- yAxis: closestPoint.yAxis
- },
- label: {
- offset: closestPoint.below ? 40 : -40,
- format: ' '
- },
- connector: {
- fill: 'none',
- stroke: closestPoint.below ?
- palette.negativeColor : palette.positiveColor
- }
- },
- shapeOptions: {
- stroke: 'rgba(0, 0, 0, 0.75)',
- strokeWidth: 1
- }
- }, navigation.annotationsOptions, navigation.bindings.verticalArrow.annotationsOptions);
- annotation = this.chart.addAnnotation(options);
- annotation.options.events.click.call(annotation, {});
- }
- },
- // Flag types:
- /**
- * A flag series bindings. Includes `start` event. On click, finds the
- * closest point and marks it with a flag with `'circlepin'` shape.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-flag-circlepin", "start": function() {}}
- */
- flagCirclepin: {
- /** @ignore-option */
- className: 'highcharts-flag-circlepin',
- /** @ignore-option */
- start: bindingsUtils.addFlagFromForm('circlepin')
- },
- /**
- * A flag series bindings. Includes `start` event. On click, finds the
- * closest point and marks it with a flag with `'diamondpin'` shape.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-flag-diamondpin", "start": function() {}}
- */
- flagDiamondpin: {
- /** @ignore-option */
- className: 'highcharts-flag-diamondpin',
- /** @ignore-option */
- start: bindingsUtils.addFlagFromForm('flag')
- },
- /**
- * A flag series bindings. Includes `start` event.
- * On click, finds the closest point and marks it with a flag with
- * `'squarepin'` shape.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-flag-squarepin", "start": function() {}}
- */
- flagSquarepin: {
- /** @ignore-option */
- className: 'highcharts-flag-squarepin',
- /** @ignore-option */
- start: bindingsUtils.addFlagFromForm('squarepin')
- },
- /**
- * A flag series bindings. Includes `start` event.
- * On click, finds the closest point and marks it with a flag without pin
- * shape.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-flag-simplepin", "start": function() {}}
- */
- flagSimplepin: {
- /** @ignore-option */
- className: 'highcharts-flag-simplepin',
- /** @ignore-option */
- start: bindingsUtils.addFlagFromForm('nopin')
- },
- // Other tools:
- /**
- * Enables zooming in xAxis on a chart. Includes `start` event which
- * changes [chart.zoomType](#chart.zoomType).
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-zoom-x", "init": function() {}}
- */
- zoomX: {
- /** @ignore-option */
- className: 'highcharts-zoom-x',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- init: function (button) {
- this.chart.update({
- chart: {
- zoomType: 'x'
- }
- });
- fireEvent(this, 'deselectButton', { button: button });
- }
- },
- /**
- * Enables zooming in yAxis on a chart. Includes `start` event which
- * changes [chart.zoomType](#chart.zoomType).
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-zoom-y", "init": function() {}}
- */
- zoomY: {
- /** @ignore-option */
- className: 'highcharts-zoom-y',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- init: function (button) {
- this.chart.update({
- chart: {
- zoomType: 'y'
- }
- });
- fireEvent(this, 'deselectButton', { button: button });
- }
- },
- /**
- * Enables zooming in xAxis and yAxis on a chart. Includes `start` event
- * which changes [chart.zoomType](#chart.zoomType).
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-zoom-xy", "init": function() {}}
- */
- zoomXY: {
- /** @ignore-option */
- className: 'highcharts-zoom-xy',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- init: function (button) {
- this.chart.update({
- chart: {
- zoomType: 'xy'
- }
- });
- fireEvent(this, 'deselectButton', { button: button });
- }
- },
- /**
- * Changes main series to `'line'` type.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-series-type-line", "init": function() {}}
- */
- seriesTypeLine: {
- /** @ignore-option */
- className: 'highcharts-series-type-line',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- init: function (button) {
- this.chart.series[0].update({
- type: 'line',
- useOhlcData: true
- });
- fireEvent(this, 'deselectButton', { button: button });
- }
- },
- /**
- * Changes main series to `'ohlc'` type.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-series-type-ohlc", "init": function() {}}
- */
- seriesTypeOhlc: {
- /** @ignore-option */
- className: 'highcharts-series-type-ohlc',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- init: function (button) {
- this.chart.series[0].update({
- type: 'ohlc'
- });
- fireEvent(this, 'deselectButton', { button: button });
- }
- },
- /**
- * Changes main series to `'candlestick'` type.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-series-type-candlestick", "init": function() {}}
- */
- seriesTypeCandlestick: {
- /** @ignore-option */
- className: 'highcharts-series-type-candlestick',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- init: function (button) {
- this.chart.series[0].update({
- type: 'candlestick'
- });
- fireEvent(this, 'deselectButton', { button: button });
- }
- },
- /**
- * Displays chart in fullscreen.
- *
- * **Note**: Fullscreen is not supported on iPhone due to iOS limitations.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "noDataState": "normal", "highcharts-full-screen", "init": function() {}}
- */
- fullScreen: {
- /** @ignore-option */
- className: 'highcharts-full-screen',
- noDataState: 'normal',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- init: function (button) {
- this.chart.fullscreen.toggle();
- fireEvent(this, 'deselectButton', { button: button });
- }
- },
- /**
- * Hides/shows two price indicators:
- * - last price in the dataset
- * - last price in the selected range
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-current-price-indicator", "init": function() {}}
- */
- currentPriceIndicator: {
- /** @ignore-option */
- className: 'highcharts-current-price-indicator',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- init: function (button) {
- var chart = this.chart, series = chart.series, gui = chart.stockTools, priceIndicatorEnabled = bindingsUtils.isPriceIndicatorEnabled(chart.series);
- if (gui && gui.guiEnabled) {
- series.forEach(function (series) {
- series.update({
- lastPrice: { enabled: !priceIndicatorEnabled },
- lastVisiblePrice: { enabled: !priceIndicatorEnabled, label: { enabled: true } }
- }, false);
- });
- chart.redraw();
- }
- fireEvent(this, 'deselectButton', { button: button });
- }
- },
- /**
- * Indicators bindings. Includes `init` event to show a popup.
- *
- * Note: In order to show base series from the chart in the popup's
- * dropdown each series requires
- * [series.id](https://api.highcharts.com/highstock/series.line.id) to be
- * defined.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-indicators", "init": function() {}}
- */
- indicators: {
- /** @ignore-option */
- className: 'highcharts-indicators',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- init: function () {
- var navigation = this;
- fireEvent(navigation, 'showPopup', {
- formType: 'indicators',
- options: {},
- // Callback on submit:
- onSubmit: function (data) {
- navigation.utils.manageIndicators.call(navigation, data);
- }
- });
- }
- },
- /**
- * Hides/shows all annotations on a chart.
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-toggle-annotations", "init": function() {}}
- */
- toggleAnnotations: {
- /** @ignore-option */
- className: 'highcharts-toggle-annotations',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- init: function (button) {
- var chart = this.chart, gui = chart.stockTools, iconsURL = gui.getIconsURL();
- this.toggledAnnotations = !this.toggledAnnotations;
- (chart.annotations || []).forEach(function (annotation) {
- annotation.setVisibility(!this.toggledAnnotations);
- }, this);
- if (gui && gui.guiEnabled) {
- if (this.toggledAnnotations) {
- button.firstChild.style['background-image'] =
- 'url("' + iconsURL +
- 'annotations-hidden.svg")';
- }
- else {
- button.firstChild.style['background-image'] =
- 'url("' + iconsURL +
- 'annotations-visible.svg")';
- }
- }
- fireEvent(this, 'deselectButton', { button: button });
- }
- },
- /**
- * Save a chart in localStorage under `highcharts-chart` key.
- * Stored items:
- * - annotations
- * - indicators (with yAxes)
- * - flags
- *
- * @type {Highcharts.NavigationBindingsOptionsObject}
- * @product highstock
- * @default {"className": "highcharts-save-chart", "noDataState": "normal", "init": function() {}}
- */
- saveChart: {
- /** @ignore-option */
- className: 'highcharts-save-chart',
- noDataState: 'normal',
- // eslint-disable-next-line valid-jsdoc
- /** @ignore-option */
- init: function (button) {
- var navigation = this, chart = navigation.chart, annotations = [], indicators = [], flags = [], yAxes = [];
- chart.annotations.forEach(function (annotation, index) {
- annotations[index] = annotation.userOptions;
- });
- chart.series.forEach(function (series) {
- if (series.is('sma')) {
- indicators.push(series.userOptions);
- }
- else if (series.type === 'flags') {
- flags.push(series.userOptions);
- }
- });
- chart.yAxis.forEach(function (yAxis) {
- if (bindingsUtils.isNotNavigatorYAxis(yAxis)) {
- yAxes.push(yAxis.options);
- }
- });
- H.win.localStorage.setItem(PREFIX + 'chart', JSON.stringify({
- annotations: annotations,
- indicators: indicators,
- flags: flags,
- yAxes: yAxes
- }));
- fireEvent(this, 'deselectButton', { button: button });
- }
- }
- };
- setOptions({
- navigation: {
- bindings: stockToolsBindings
- }
- });
- NavigationBindings.prototype.utils = merge(bindingsUtils, NavigationBindings.prototype.utils);
|