5905 lines
233 KiB
JavaScript
5905 lines
233 KiB
JavaScript
/* *
|
|
*
|
|
* (c) 2010-2020 Torstein Honsi
|
|
*
|
|
* License: www.highcharts.com/license
|
|
*
|
|
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
*
|
|
* */
|
|
'use strict';
|
|
import Color from './Color.js';
|
|
import H from './Globals.js';
|
|
import Tick from './Tick.js';
|
|
import U from './Utilities.js';
|
|
var addEvent = U.addEvent, animObject = U.animObject, arrayMax = U.arrayMax, arrayMin = U.arrayMin, clamp = U.clamp, correctFloat = U.correctFloat, defined = U.defined, destroyObjectProperties = U.destroyObjectProperties, error = U.error, extend = U.extend, fireEvent = U.fireEvent, format = U.format, getMagnitude = U.getMagnitude, isArray = U.isArray, isFunction = U.isFunction, isNumber = U.isNumber, isString = U.isString, merge = U.merge, normalizeTickInterval = U.normalizeTickInterval, objectEach = U.objectEach, pick = U.pick, relativeLength = U.relativeLength, removeEvent = U.removeEvent, splat = U.splat, syncTimeout = U.syncTimeout;
|
|
/**
|
|
* Options for the path on the Axis to be calculated.
|
|
* @interface Highcharts.AxisPlotLinePathOptionsObject
|
|
*/ /**
|
|
* Axis value.
|
|
* @name Highcharts.AxisPlotLinePathOptionsObject#value
|
|
* @type {number|undefined}
|
|
*/ /**
|
|
* Line width used for calculation crisp line coordinates. Defaults to 1.
|
|
* @name Highcharts.AxisPlotLinePathOptionsObject#lineWidth
|
|
* @type {number|undefined}
|
|
*/ /**
|
|
* If `false`, the function will return null when it falls outside the axis
|
|
* bounds. If `true`, the function will return a path aligned to the plot area
|
|
* sides if it falls outside. If `pass`, it will return a path outside.
|
|
* @name Highcharts.AxisPlotLinePathOptionsObject#force
|
|
* @type {string|boolean|undefined}
|
|
*/ /**
|
|
* Used in Highstock. When `true`, plot paths (crosshair, plotLines, gridLines)
|
|
* will be rendered on all axes when defined on the first axis.
|
|
* @name Highcharts.AxisPlotLinePathOptionsObject#acrossPanes
|
|
* @type {boolean|undefined}
|
|
*/ /**
|
|
* Use old coordinates (for resizing and rescaling).
|
|
* If not set, defaults to `false`.
|
|
* @name Highcharts.AxisPlotLinePathOptionsObject#old
|
|
* @type {boolean|undefined}
|
|
*/ /**
|
|
* If given, return the plot line path of a pixel position on the axis.
|
|
* @name Highcharts.AxisPlotLinePathOptionsObject#translatedValue
|
|
* @type {number|undefined}
|
|
*/ /**
|
|
* Used in Polar axes. Reverse the positions for concatenation of polygonal
|
|
* plot bands
|
|
* @name Highcharts.AxisPlotLinePathOptionsObject#reverse
|
|
* @type {boolean|undefined}
|
|
*/
|
|
/**
|
|
* Options for crosshairs on axes.
|
|
*
|
|
* @product highstock
|
|
*
|
|
* @typedef {Highcharts.XAxisCrosshairOptions|Highcharts.YAxisCrosshairOptions} Highcharts.AxisCrosshairOptions
|
|
*/
|
|
/**
|
|
* @typedef {"navigator"|"pan"|"rangeSelectorButton"|"rangeSelectorInput"|"scrollbar"|"traverseUpButton"|"zoom"} Highcharts.AxisExtremesTriggerValue
|
|
*/
|
|
/**
|
|
* @callback Highcharts.AxisEventCallbackFunction
|
|
*
|
|
* @param {Highcharts.Axis} this
|
|
*/
|
|
/**
|
|
* @interface Highcharts.AxisLabelsFormatterContextObject
|
|
*/ /**
|
|
* @name Highcharts.AxisLabelsFormatterContextObject#axis
|
|
* @type {Highcharts.Axis}
|
|
*/ /**
|
|
* @name Highcharts.AxisLabelsFormatterContextObject#chart
|
|
* @type {Highcharts.Chart}
|
|
*/ /**
|
|
* @name Highcharts.AxisLabelsFormatterContextObject#isFirst
|
|
* @type {boolean}
|
|
*/ /**
|
|
* @name Highcharts.AxisLabelsFormatterContextObject#isLast
|
|
* @type {boolean}
|
|
*/ /**
|
|
* @name Highcharts.AxisLabelsFormatterContextObject#pos
|
|
* @type {number}
|
|
*/ /**
|
|
* @name Highcharts.AxisLabelsFormatterContextObject#value
|
|
* @type {number}
|
|
*/
|
|
/**
|
|
* Options for axes.
|
|
*
|
|
* @typedef {Highcharts.XAxisOptions|Highcharts.YAxisOptions|Highcharts.ZAxisOptions} Highcharts.AxisOptions
|
|
*/
|
|
/**
|
|
* @callback Highcharts.AxisPointBreakEventCallbackFunction
|
|
*
|
|
* @param {Highcharts.Axis} this
|
|
*
|
|
* @param {Highcharts.AxisPointBreakEventObject} evt
|
|
*/
|
|
/**
|
|
* @interface Highcharts.AxisPointBreakEventObject
|
|
*/ /**
|
|
* @name Highcharts.AxisPointBreakEventObject#brk
|
|
* @type {Highcharts.Dictionary<number>}
|
|
*/ /**
|
|
* @name Highcharts.AxisPointBreakEventObject#point
|
|
* @type {Highcharts.Point}
|
|
*/ /**
|
|
* @name Highcharts.AxisPointBreakEventObject#preventDefault
|
|
* @type {Function}
|
|
*/ /**
|
|
* @name Highcharts.AxisPointBreakEventObject#target
|
|
* @type {Highcharts.SVGElement}
|
|
*/ /**
|
|
* @name Highcharts.AxisPointBreakEventObject#type
|
|
* @type {"pointBreak"|"pointInBreak"}
|
|
*/
|
|
/**
|
|
* @callback Highcharts.AxisSetExtremesEventCallbackFunction
|
|
*
|
|
* @param {Highcharts.Axis} this
|
|
*
|
|
* @param {Highcharts.AxisSetExtremesEventObject} evt
|
|
*/
|
|
/**
|
|
* @interface Highcharts.AxisSetExtremesEventObject
|
|
* @extends Highcharts.ExtremesObject
|
|
*/ /**
|
|
* @name Highcharts.AxisSetExtremesEventObject#preventDefault
|
|
* @type {Function}
|
|
*/ /**
|
|
* @name Highcharts.AxisSetExtremesEventObject#target
|
|
* @type {Highcharts.SVGElement}
|
|
*/ /**
|
|
* @name Highcharts.AxisSetExtremesEventObject#trigger
|
|
* @type {Highcharts.AxisExtremesTriggerValue|string}
|
|
*/ /**
|
|
* @name Highcharts.AxisSetExtremesEventObject#type
|
|
* @type {"setExtremes"}
|
|
*/
|
|
/**
|
|
* @callback Highcharts.AxisTickPositionerCallbackFunction
|
|
*
|
|
* @param {Highcharts.Axis} this
|
|
*
|
|
* @return {Array<number>}
|
|
*/
|
|
/**
|
|
* @interface Highcharts.AxisTickPositionsArray
|
|
* @augments Array<number>
|
|
*/
|
|
/**
|
|
* @typedef {"high"|"low"|"middle"} Highcharts.AxisTitleAlignValue
|
|
*/
|
|
/**
|
|
* @typedef {Highcharts.XAxisTitleOptions|Highcharts.YAxisTitleOptions|Highcharts.ZAxisTitleOptions} Highcharts.AxisTitleOptions
|
|
*/
|
|
/**
|
|
* @typedef {"linear"|"logarithmic"|"datetime"|"category"|"treegrid"} Highcharts.AxisTypeValue
|
|
*/
|
|
/**
|
|
* The returned object literal from the {@link Highcharts.Axis#getExtremes}
|
|
* function.
|
|
*
|
|
* @interface Highcharts.ExtremesObject
|
|
*/ /**
|
|
* The maximum value of the axis' associated series.
|
|
* @name Highcharts.ExtremesObject#dataMax
|
|
* @type {number}
|
|
*/ /**
|
|
* The minimum value of the axis' associated series.
|
|
* @name Highcharts.ExtremesObject#dataMin
|
|
* @type {number}
|
|
*/ /**
|
|
* The maximum axis value, either automatic or set manually. If the `max` option
|
|
* is not set, `maxPadding` is 0 and `endOnTick` is false, this value will be
|
|
* the same as `dataMax`.
|
|
* @name Highcharts.ExtremesObject#max
|
|
* @type {number}
|
|
*/ /**
|
|
* The minimum axis value, either automatic or set manually. If the `min` option
|
|
* is not set, `minPadding` is 0 and `startOnTick` is false, this value will be
|
|
* the same as `dataMin`.
|
|
* @name Highcharts.ExtremesObject#min
|
|
* @type {number}
|
|
*/ /**
|
|
* The user defined maximum, either from the `max` option or from a zoom or
|
|
* `setExtremes` action.
|
|
* @name Highcharts.ExtremesObject#userMax
|
|
* @type {number}
|
|
*/ /**
|
|
* The user defined minimum, either from the `min` option or from a zoom or
|
|
* `setExtremes` action.
|
|
* @name Highcharts.ExtremesObject#userMin
|
|
* @type {number}
|
|
*/
|
|
/**
|
|
* Formatter function for the text of a crosshair label.
|
|
*
|
|
* @callback Highcharts.XAxisCrosshairLabelFormatterCallbackFunction
|
|
*
|
|
* @param {Highcharts.Axis} this
|
|
* Axis context
|
|
*
|
|
* @param {number} value
|
|
* Y value of the data point
|
|
*
|
|
* @return {string}
|
|
*/
|
|
import './Options.js';
|
|
var defaultOptions = H.defaultOptions, deg2rad = H.deg2rad;
|
|
/**
|
|
* Create a new axis object. Called internally when instanciating a new chart or
|
|
* adding axes by {@link Highcharts.Chart#addAxis}.
|
|
*
|
|
* A chart can have from 0 axes (pie chart) to multiples. In a normal, single
|
|
* series cartesian chart, there is one X axis and one Y axis.
|
|
*
|
|
* The X axis or axes are referenced by {@link Highcharts.Chart.xAxis}, which is
|
|
* an array of Axis objects. If there is only one axis, it can be referenced
|
|
* through `chart.xAxis[0]`, and multiple axes have increasing indices. The same
|
|
* pattern goes for Y axes.
|
|
*
|
|
* If you need to get the axes from a series object, use the `series.xAxis` and
|
|
* `series.yAxis` properties. These are not arrays, as one series can only be
|
|
* associated to one X and one Y axis.
|
|
*
|
|
* A third way to reference the axis programmatically is by `id`. Add an `id` in
|
|
* the axis configuration options, and get the axis by
|
|
* {@link Highcharts.Chart#get}.
|
|
*
|
|
* Configuration options for the axes are given in options.xAxis and
|
|
* options.yAxis.
|
|
*
|
|
* @class
|
|
* @name Highcharts.Axis
|
|
*
|
|
* @param {Highcharts.Chart} chart
|
|
* The Chart instance to apply the axis on.
|
|
*
|
|
* @param {Highcharts.AxisOptions} userOptions
|
|
* Axis options.
|
|
*/
|
|
var Axis = /** @class */ (function () {
|
|
/* *
|
|
*
|
|
* Constructors
|
|
*
|
|
* */
|
|
function Axis(chart, userOptions) {
|
|
this.alternateBands = void 0;
|
|
this.bottom = void 0;
|
|
this.categories = void 0;
|
|
this.chart = void 0;
|
|
this.closestPointRange = void 0;
|
|
this.coll = void 0;
|
|
this.hasNames = void 0;
|
|
this.hasVisibleSeries = void 0;
|
|
this.height = void 0;
|
|
this.isLinked = void 0;
|
|
this.labelEdge = void 0; // @todo
|
|
this.labelFormatter = void 0;
|
|
this.left = void 0;
|
|
this.len = void 0;
|
|
this.max = void 0;
|
|
this.maxLabelLength = void 0;
|
|
this.min = void 0;
|
|
this.minorTickInterval = void 0;
|
|
this.minorTicks = void 0;
|
|
this.minPixelPadding = void 0;
|
|
this.names = void 0;
|
|
this.offset = void 0;
|
|
this.oldMax = void 0;
|
|
this.oldMin = void 0;
|
|
this.options = void 0;
|
|
this.overlap = void 0;
|
|
this.paddedTicks = void 0;
|
|
this.plotLinesAndBands = void 0;
|
|
this.plotLinesAndBandsGroups = void 0;
|
|
this.pointRange = void 0;
|
|
this.pointRangePadding = void 0;
|
|
this.pos = void 0;
|
|
this.positiveValuesOnly = void 0;
|
|
this.right = void 0;
|
|
this.series = void 0;
|
|
this.side = void 0;
|
|
this.tickAmount = void 0;
|
|
this.tickInterval = void 0;
|
|
this.tickmarkOffset = void 0;
|
|
this.tickPositions = void 0;
|
|
this.tickRotCorr = void 0;
|
|
this.ticks = void 0;
|
|
this.top = void 0;
|
|
this.transA = void 0;
|
|
this.transB = void 0;
|
|
this.translationSlope = void 0;
|
|
this.userOptions = void 0;
|
|
this.visible = void 0;
|
|
this.width = void 0;
|
|
this.zoomEnabled = void 0;
|
|
this.init(chart, userOptions);
|
|
}
|
|
/* *
|
|
*
|
|
* Functions
|
|
*
|
|
* */
|
|
/**
|
|
* Overrideable function to initialize the axis.
|
|
*
|
|
* @see {@link Axis}
|
|
*
|
|
* @function Highcharts.Axis#init
|
|
*
|
|
* @param {Highcharts.Chart} chart
|
|
* The Chart instance to apply the axis on.
|
|
*
|
|
* @param {Highcharts.AxisOptions} userOptions
|
|
* Axis options.
|
|
*
|
|
* @fires Highcharts.Axis#event:afterInit
|
|
* @fires Highcharts.Axis#event:init
|
|
*/
|
|
Axis.prototype.init = function (chart, userOptions) {
|
|
var isXAxis = userOptions.isX, axis = this;
|
|
/**
|
|
* The Chart that the axis belongs to.
|
|
*
|
|
* @name Highcharts.Axis#chart
|
|
* @type {Highcharts.Chart}
|
|
*/
|
|
axis.chart = chart;
|
|
/**
|
|
* Whether the axis is horizontal.
|
|
*
|
|
* @name Highcharts.Axis#horiz
|
|
* @type {boolean|undefined}
|
|
*/
|
|
axis.horiz = chart.inverted && !axis.isZAxis ? !isXAxis : isXAxis;
|
|
/**
|
|
* Whether the axis is the x-axis.
|
|
*
|
|
* @name Highcharts.Axis#isXAxis
|
|
* @type {boolean|undefined}
|
|
*/
|
|
axis.isXAxis = isXAxis;
|
|
/**
|
|
* The collection where the axis belongs, for example `xAxis`, `yAxis`
|
|
* or `colorAxis`. Corresponds to properties on Chart, for example
|
|
* {@link Chart.xAxis}.
|
|
*
|
|
* @name Highcharts.Axis#coll
|
|
* @type {string}
|
|
*/
|
|
axis.coll = axis.coll || (isXAxis ? 'xAxis' : 'yAxis');
|
|
fireEvent(this, 'init', { userOptions: userOptions });
|
|
axis.opposite = userOptions.opposite; // needed in setOptions
|
|
/**
|
|
* The side on which the axis is rendered. 0 is top, 1 is right, 2
|
|
* is bottom and 3 is left.
|
|
*
|
|
* @name Highcharts.Axis#side
|
|
* @type {number}
|
|
*/
|
|
axis.side = userOptions.side || (axis.horiz ?
|
|
(axis.opposite ? 0 : 2) : // top : bottom
|
|
(axis.opposite ? 1 : 3)); // right : left
|
|
/**
|
|
* Current options for the axis after merge of defaults and user's
|
|
* options.
|
|
*
|
|
* @name Highcharts.Axis#options
|
|
* @type {Highcharts.AxisOptions}
|
|
*/
|
|
axis.setOptions(userOptions);
|
|
var options = this.options, type = options.type;
|
|
axis.labelFormatter = (options.labels.formatter ||
|
|
// can be overwritten by dynamic format
|
|
axis.defaultLabelFormatter);
|
|
/**
|
|
* User's options for this axis without defaults.
|
|
*
|
|
* @name Highcharts.Axis#userOptions
|
|
* @type {Highcharts.AxisOptions}
|
|
*/
|
|
axis.userOptions = userOptions;
|
|
axis.minPixelPadding = 0;
|
|
/**
|
|
* Whether the axis is reversed. Based on the `axis.reversed`,
|
|
* option, but inverted charts have reversed xAxis by default.
|
|
*
|
|
* @name Highcharts.Axis#reversed
|
|
* @type {boolean}
|
|
*/
|
|
axis.reversed = options.reversed;
|
|
axis.visible = options.visible !== false;
|
|
axis.zoomEnabled = options.zoomEnabled !== false;
|
|
// Initial categories
|
|
axis.hasNames =
|
|
type === 'category' || options.categories === true;
|
|
/**
|
|
* If categories are present for the axis, names are used instead of
|
|
* numbers for that axis.
|
|
*
|
|
* Since Highcharts 3.0, categories can also be extracted by giving each
|
|
* point a name and setting axis type to `category`. However, if you
|
|
* have multiple series, best practice remains defining the `categories`
|
|
* array.
|
|
*
|
|
* @see [xAxis.categories](/highcharts/xAxis.categories)
|
|
*
|
|
* @name Highcharts.Axis#categories
|
|
* @type {Array<string>}
|
|
* @readonly
|
|
*/
|
|
axis.categories = options.categories || axis.hasNames;
|
|
if (!axis.names) { // Preserve on update (#3830)
|
|
axis.names = [];
|
|
axis.names.keys = {};
|
|
}
|
|
// Placeholder for plotlines and plotbands groups
|
|
axis.plotLinesAndBandsGroups = {};
|
|
// Shorthand types
|
|
axis.positiveValuesOnly = !!(axis.logarithmic && !options.allowNegativeLog);
|
|
// Flag, if axis is linked to another axis
|
|
axis.isLinked = defined(options.linkedTo);
|
|
/**
|
|
* List of major ticks mapped by postition on axis.
|
|
*
|
|
* @see {@link Highcharts.Tick}
|
|
*
|
|
* @name Highcharts.Axis#ticks
|
|
* @type {Highcharts.Dictionary<Highcharts.Tick>}
|
|
*/
|
|
axis.ticks = {};
|
|
axis.labelEdge = [];
|
|
/**
|
|
* List of minor ticks mapped by position on the axis.
|
|
*
|
|
* @see {@link Highcharts.Tick}
|
|
*
|
|
* @name Highcharts.Axis#minorTicks
|
|
* @type {Highcharts.Dictionary<Highcharts.Tick>}
|
|
*/
|
|
axis.minorTicks = {};
|
|
// List of plotLines/Bands
|
|
axis.plotLinesAndBands = [];
|
|
// Alternate bands
|
|
axis.alternateBands = {};
|
|
// Axis metrics
|
|
axis.len = 0;
|
|
axis.minRange = axis.userMinRange = options.minRange || options.maxZoom;
|
|
axis.range = options.range;
|
|
axis.offset = options.offset || 0;
|
|
/**
|
|
* The maximum value of the axis. In a logarithmic axis, this is the
|
|
* logarithm of the real value, and the real value can be obtained from
|
|
* {@link Axis#getExtremes}.
|
|
*
|
|
* @name Highcharts.Axis#max
|
|
* @type {number|null}
|
|
*/
|
|
axis.max = null;
|
|
/**
|
|
* The minimum value of the axis. In a logarithmic axis, this is the
|
|
* logarithm of the real value, and the real value can be obtained from
|
|
* {@link Axis#getExtremes}.
|
|
*
|
|
* @name Highcharts.Axis#min
|
|
* @type {number|null}
|
|
*/
|
|
axis.min = null;
|
|
/**
|
|
* The processed crosshair options.
|
|
*
|
|
* @name Highcharts.Axis#crosshair
|
|
* @type {boolean|Highcharts.AxisCrosshairOptions}
|
|
*/
|
|
axis.crosshair = pick(options.crosshair, splat(chart.options.tooltip.crosshairs)[isXAxis ? 0 : 1], false);
|
|
var events = axis.options.events;
|
|
// Register. Don't add it again on Axis.update().
|
|
if (chart.axes.indexOf(axis) === -1) { //
|
|
if (isXAxis) { // #2713
|
|
chart.axes.splice(chart.xAxis.length, 0, axis);
|
|
}
|
|
else {
|
|
chart.axes.push(axis);
|
|
}
|
|
chart[axis.coll].push(axis);
|
|
}
|
|
/**
|
|
* All series associated to the axis.
|
|
*
|
|
* @name Highcharts.Axis#series
|
|
* @type {Array<Highcharts.Series>}
|
|
*/
|
|
axis.series = axis.series || []; // populated by Series
|
|
// Reversed axis
|
|
if (chart.inverted &&
|
|
!axis.isZAxis &&
|
|
isXAxis &&
|
|
typeof axis.reversed === 'undefined') {
|
|
axis.reversed = true;
|
|
}
|
|
axis.labelRotation = axis.options.labels.rotation;
|
|
// register event listeners
|
|
objectEach(events, function (event, eventType) {
|
|
if (isFunction(event)) {
|
|
addEvent(axis, eventType, event);
|
|
}
|
|
});
|
|
fireEvent(this, 'afterInit');
|
|
};
|
|
/**
|
|
* Merge and set options.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#setOptions
|
|
*
|
|
* @param {Highcharts.AxisOptions} userOptions
|
|
* Axis options.
|
|
*
|
|
* @fires Highcharts.Axis#event:afterSetOptions
|
|
*/
|
|
Axis.prototype.setOptions = function (userOptions) {
|
|
this.options = merge(Axis.defaultOptions, (this.coll === 'yAxis') && Axis.defaultYAxisOptions, [
|
|
Axis.defaultTopAxisOptions,
|
|
Axis.defaultRightAxisOptions,
|
|
Axis.defaultBottomAxisOptions,
|
|
Axis.defaultLeftAxisOptions
|
|
][this.side], merge(
|
|
// if set in setOptions (#1053):
|
|
defaultOptions[this.coll], userOptions));
|
|
fireEvent(this, 'afterSetOptions', { userOptions: userOptions });
|
|
};
|
|
/**
|
|
* The default label formatter. The context is a special config object for
|
|
* the label. In apps, use the
|
|
* [labels.formatter](https://api.highcharts.com/highcharts/xAxis.labels.formatter)
|
|
* instead, except when a modification is needed.
|
|
*
|
|
* @function Highcharts.Axis#defaultLabelFormatter
|
|
*
|
|
* @param {Highcharts.AxisLabelsFormatterContextObject} this
|
|
* Formatter context of axis label.
|
|
*
|
|
* @return {string}
|
|
* The formatted label content.
|
|
*/
|
|
Axis.prototype.defaultLabelFormatter = function () {
|
|
var axis = this.axis, value = this.value, time = axis.chart.time, categories = axis.categories, dateTimeLabelFormat = this.dateTimeLabelFormat, lang = defaultOptions.lang, numericSymbols = lang.numericSymbols, numSymMagnitude = lang.numericSymbolMagnitude || 1000, i = numericSymbols && numericSymbols.length, multi, ret, formatOption = axis.options.labels.format,
|
|
// make sure the same symbol is added for all labels on a linear
|
|
// axis
|
|
numericSymbolDetector = axis.logarithmic ?
|
|
Math.abs(value) :
|
|
axis.tickInterval;
|
|
var chart = this.chart;
|
|
var numberFormatter = chart.numberFormatter;
|
|
if (formatOption) {
|
|
ret = format(formatOption, this, chart);
|
|
}
|
|
else if (categories) {
|
|
ret = value;
|
|
}
|
|
else if (dateTimeLabelFormat) { // datetime axis
|
|
ret = time.dateFormat(dateTimeLabelFormat, value);
|
|
}
|
|
else if (i && numericSymbolDetector >= 1000) {
|
|
// Decide whether we should add a numeric symbol like k (thousands)
|
|
// or M (millions). If we are to enable this in tooltip or other
|
|
// places as well, we can move this logic to the numberFormatter and
|
|
// enable it by a parameter.
|
|
while (i-- && typeof ret === 'undefined') {
|
|
multi = Math.pow(numSymMagnitude, i + 1);
|
|
if (
|
|
// Only accept a numeric symbol when the distance is more
|
|
// than a full unit. So for example if the symbol is k, we
|
|
// don't accept numbers like 0.5k.
|
|
numericSymbolDetector >= multi &&
|
|
// Accept one decimal before the symbol. Accepts 0.5k but
|
|
// not 0.25k. How does this work with the previous?
|
|
(value * 10) % multi === 0 &&
|
|
numericSymbols[i] !== null &&
|
|
value !== 0) { // #5480
|
|
ret = numberFormatter(value / multi, -1) +
|
|
numericSymbols[i];
|
|
}
|
|
}
|
|
}
|
|
if (typeof ret === 'undefined') {
|
|
if (Math.abs(value) >= 10000) { // add thousands separators
|
|
ret = numberFormatter(value, -1);
|
|
}
|
|
else { // small numbers
|
|
ret = numberFormatter(value, -1, void 0, ''); // #2466
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
/**
|
|
* Get the minimum and maximum for the series of each axis. The function
|
|
* analyzes the axis series and updates `this.dataMin` and `this.dataMax`.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#getSeriesExtremes
|
|
*
|
|
* @fires Highcharts.Axis#event:afterGetSeriesExtremes
|
|
* @fires Highcharts.Axis#event:getSeriesExtremes
|
|
*/
|
|
Axis.prototype.getSeriesExtremes = function () {
|
|
var axis = this, chart = axis.chart, xExtremes;
|
|
fireEvent(this, 'getSeriesExtremes', null, function () {
|
|
axis.hasVisibleSeries = false;
|
|
// Reset properties in case we're redrawing (#3353)
|
|
axis.dataMin = axis.dataMax = axis.threshold = null;
|
|
axis.softThreshold = !axis.isXAxis;
|
|
if (axis.stacking) {
|
|
axis.stacking.buildStacks();
|
|
}
|
|
// loop through this axis' series
|
|
axis.series.forEach(function (series) {
|
|
if (series.visible ||
|
|
!chart.options.chart.ignoreHiddenSeries) {
|
|
var seriesOptions = series.options, xData, threshold = seriesOptions.threshold, seriesDataMin, seriesDataMax;
|
|
axis.hasVisibleSeries = true;
|
|
// Validate threshold in logarithmic axes
|
|
if (axis.positiveValuesOnly && threshold <= 0) {
|
|
threshold = null;
|
|
}
|
|
// Get dataMin and dataMax for X axes
|
|
if (axis.isXAxis) {
|
|
xData = series.xData;
|
|
if (xData.length) {
|
|
xExtremes = series.getXExtremes(xData);
|
|
// If xData contains values which is not numbers,
|
|
// then filter them out. To prevent performance hit,
|
|
// we only do this after we have already found
|
|
// seriesDataMin because in most cases all data is
|
|
// valid. #5234.
|
|
seriesDataMin = xExtremes.min;
|
|
seriesDataMax = xExtremes.max;
|
|
if (!isNumber(seriesDataMin) &&
|
|
// #5010:
|
|
!(seriesDataMin instanceof Date)) {
|
|
xData = xData.filter(isNumber);
|
|
xExtremes = series.getXExtremes(xData);
|
|
// Do it again with valid data
|
|
seriesDataMin = xExtremes.min;
|
|
seriesDataMax = xExtremes.max;
|
|
}
|
|
if (xData.length) {
|
|
axis.dataMin = Math.min(pick(axis.dataMin, seriesDataMin), seriesDataMin);
|
|
axis.dataMax = Math.max(pick(axis.dataMax, seriesDataMax), seriesDataMax);
|
|
}
|
|
}
|
|
// Get dataMin and dataMax for Y axes, as well as handle
|
|
// stacking and processed data
|
|
}
|
|
else {
|
|
// Get this particular series extremes
|
|
var dataExtremes = series.applyExtremes();
|
|
// Get the dataMin and dataMax so far. If percentage is
|
|
// used, the min and max are always 0 and 100. If
|
|
// seriesDataMin and seriesDataMax is null, then series
|
|
// doesn't have active y data, we continue with nulls
|
|
if (isNumber(dataExtremes.dataMin)) {
|
|
seriesDataMin = dataExtremes.dataMin;
|
|
axis.dataMin = Math.min(pick(axis.dataMin, seriesDataMin), seriesDataMin);
|
|
}
|
|
if (isNumber(dataExtremes.dataMax)) {
|
|
seriesDataMax = dataExtremes.dataMax;
|
|
axis.dataMax = Math.max(pick(axis.dataMax, seriesDataMax), seriesDataMax);
|
|
}
|
|
// Adjust to threshold
|
|
if (defined(threshold)) {
|
|
axis.threshold = threshold;
|
|
}
|
|
// If any series has a hard threshold, it takes
|
|
// precedence
|
|
if (!seriesOptions.softThreshold ||
|
|
axis.positiveValuesOnly) {
|
|
axis.softThreshold = false;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
fireEvent(this, 'afterGetSeriesExtremes');
|
|
};
|
|
/**
|
|
* Translate from axis value to pixel position on the chart, or back. Use
|
|
* the `toPixels` and `toValue` functions in applications.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#translate
|
|
*
|
|
* @param {number} val
|
|
* TO-DO: parameter description
|
|
*
|
|
* @param {boolean|null} [backwards]
|
|
* TO-DO: parameter description
|
|
*
|
|
* @param {boolean|null} [cvsCoord]
|
|
* TO-DO: parameter description
|
|
*
|
|
* @param {boolean|null} [old]
|
|
* TO-DO: parameter description
|
|
*
|
|
* @param {boolean} [handleLog]
|
|
* TO-DO: parameter description
|
|
*
|
|
* @param {number} [pointPlacement]
|
|
* TO-DO: parameter description
|
|
*
|
|
* @return {number|undefined}
|
|
*/
|
|
Axis.prototype.translate = function (val, backwards, cvsCoord, old, handleLog, pointPlacement) {
|
|
var axis = this.linkedParent || this, // #1417
|
|
sign = 1, cvsOffset = 0, localA = old ? axis.oldTransA : axis.transA, localMin = old ? axis.oldMin : axis.min, returnValue = 0, minPixelPadding = axis.minPixelPadding, doPostTranslate = (axis.isOrdinal ||
|
|
axis.brokenAxis && axis.brokenAxis.hasBreaks ||
|
|
(axis.logarithmic && handleLog)) && axis.lin2val;
|
|
if (!localA) {
|
|
localA = axis.transA;
|
|
}
|
|
// In vertical axes, the canvas coordinates start from 0 at the top like
|
|
// in SVG.
|
|
if (cvsCoord) {
|
|
sign *= -1; // canvas coordinates inverts the value
|
|
cvsOffset = axis.len;
|
|
}
|
|
// Handle reversed axis
|
|
if (axis.reversed) {
|
|
sign *= -1;
|
|
cvsOffset -= sign * (axis.sector || axis.len);
|
|
}
|
|
// From pixels to value
|
|
if (backwards) { // reverse translation
|
|
val = val * sign + cvsOffset;
|
|
val -= minPixelPadding;
|
|
// from chart pixel to value:
|
|
returnValue = val / localA + localMin;
|
|
if (doPostTranslate) { // log and ordinal axes
|
|
returnValue = axis.lin2val(returnValue);
|
|
}
|
|
// From value to pixels
|
|
}
|
|
else {
|
|
if (doPostTranslate) { // log and ordinal axes
|
|
val = axis.val2lin(val);
|
|
}
|
|
returnValue = isNumber(localMin) ?
|
|
(sign * (val - localMin) * localA +
|
|
cvsOffset +
|
|
(sign * minPixelPadding) +
|
|
(isNumber(pointPlacement) ?
|
|
localA * pointPlacement :
|
|
0)) :
|
|
void 0;
|
|
}
|
|
return returnValue;
|
|
};
|
|
/**
|
|
* Translate a value in terms of axis units into pixels within the chart.
|
|
*
|
|
* @function Highcharts.Axis#toPixels
|
|
*
|
|
* @param {number} value
|
|
* A value in terms of axis units.
|
|
*
|
|
* @param {boolean} paneCoordinates
|
|
* Whether to return the pixel coordinate relative to the chart or just the
|
|
* axis/pane itself.
|
|
*
|
|
* @return {number}
|
|
* Pixel position of the value on the chart or axis.
|
|
*/
|
|
Axis.prototype.toPixels = function (value, paneCoordinates) {
|
|
return this.translate(value, false, !this.horiz, null, true) +
|
|
(paneCoordinates ? 0 : this.pos);
|
|
};
|
|
/**
|
|
* Translate a pixel position along the axis to a value in terms of axis
|
|
* units.
|
|
*
|
|
* @function Highcharts.Axis#toValue
|
|
*
|
|
* @param {number} pixel
|
|
* The pixel value coordinate.
|
|
*
|
|
* @param {boolean} [paneCoordinates=false]
|
|
* Whether the input pixel is relative to the chart or just the axis/pane
|
|
* itself.
|
|
*
|
|
* @return {number}
|
|
* The axis value.
|
|
*/
|
|
Axis.prototype.toValue = function (pixel, paneCoordinates) {
|
|
return this.translate(pixel - (paneCoordinates ? 0 : this.pos), true, !this.horiz, null, true);
|
|
};
|
|
/**
|
|
* Create the path for a plot line that goes from the given value on
|
|
* this axis, across the plot to the opposite side. Also used internally for
|
|
* grid lines and crosshairs.
|
|
*
|
|
* @function Highcharts.Axis#getPlotLinePath
|
|
*
|
|
* @param {Highcharts.AxisPlotLinePathOptionsObject} options
|
|
* Options for the path.
|
|
*
|
|
* @return {Highcharts.SVGPathArray|null}
|
|
* The SVG path definition for the plot line.
|
|
*/
|
|
Axis.prototype.getPlotLinePath = function (options) {
|
|
var axis = this, chart = axis.chart, axisLeft = axis.left, axisTop = axis.top, old = options.old, value = options.value, translatedValue = options.translatedValue, lineWidth = options.lineWidth, force = options.force, x1, y1, x2, y2, cHeight = (old && chart.oldChartHeight) || chart.chartHeight, cWidth = (old && chart.oldChartWidth) || chart.chartWidth, skip, transB = axis.transB, evt;
|
|
// eslint-disable-next-line valid-jsdoc
|
|
/**
|
|
* Check if x is between a and b. If not, either move to a/b
|
|
* or skip, depending on the force parameter.
|
|
* @private
|
|
*/
|
|
function between(x, a, b) {
|
|
if (force !== 'pass' && x < a || x > b) {
|
|
if (force) {
|
|
x = clamp(x, a, b);
|
|
}
|
|
else {
|
|
skip = true;
|
|
}
|
|
}
|
|
return x;
|
|
}
|
|
evt = {
|
|
value: value,
|
|
lineWidth: lineWidth,
|
|
old: old,
|
|
force: force,
|
|
acrossPanes: options.acrossPanes,
|
|
translatedValue: translatedValue
|
|
};
|
|
fireEvent(this, 'getPlotLinePath', evt, function (e) {
|
|
translatedValue = pick(translatedValue, axis.translate(value, null, null, old));
|
|
// Keep the translated value within sane bounds, and avoid Infinity
|
|
// to fail the isNumber test (#7709).
|
|
translatedValue = clamp(translatedValue, -1e5, 1e5);
|
|
x1 = x2 = Math.round(translatedValue + transB);
|
|
y1 = y2 = Math.round(cHeight - translatedValue - transB);
|
|
if (!isNumber(translatedValue)) { // no min or max
|
|
skip = true;
|
|
force = false; // #7175, don't force it when path is invalid
|
|
}
|
|
else if (axis.horiz) {
|
|
y1 = axisTop;
|
|
y2 = cHeight - axis.bottom;
|
|
x1 = x2 = between(x1, axisLeft, axisLeft + axis.width);
|
|
}
|
|
else {
|
|
x1 = axisLeft;
|
|
x2 = cWidth - axis.right;
|
|
y1 = y2 = between(y1, axisTop, axisTop + axis.height);
|
|
}
|
|
e.path = skip && !force ?
|
|
null :
|
|
chart.renderer.crispLine([['M', x1, y1], ['L', x2, y2]], lineWidth || 1);
|
|
});
|
|
return evt.path;
|
|
};
|
|
/**
|
|
* Internal function to et the tick positions of a linear axis to round
|
|
* values like whole tens or every five.
|
|
*
|
|
* @function Highcharts.Axis#getLinearTickPositions
|
|
*
|
|
* @param {number} tickInterval
|
|
* The normalized tick interval.
|
|
*
|
|
* @param {number} min
|
|
* Axis minimum.
|
|
*
|
|
* @param {number} max
|
|
* Axis maximum.
|
|
*
|
|
* @return {Array<number>}
|
|
* An array of axis values where ticks should be placed.
|
|
*/
|
|
Axis.prototype.getLinearTickPositions = function (tickInterval, min, max) {
|
|
var pos, lastPos, roundedMin = correctFloat(Math.floor(min / tickInterval) * tickInterval), roundedMax = correctFloat(Math.ceil(max / tickInterval) * tickInterval), tickPositions = [], precision;
|
|
// When the precision is higher than what we filter out in
|
|
// correctFloat, skip it (#6183).
|
|
if (correctFloat(roundedMin + tickInterval) === roundedMin) {
|
|
precision = 20;
|
|
}
|
|
// For single points, add a tick regardless of the relative position
|
|
// (#2662, #6274)
|
|
if (this.single) {
|
|
return [min];
|
|
}
|
|
// Populate the intermediate values
|
|
pos = roundedMin;
|
|
while (pos <= roundedMax) {
|
|
// Place the tick on the rounded value
|
|
tickPositions.push(pos);
|
|
// Always add the raw tickInterval, not the corrected one.
|
|
pos = correctFloat(pos + tickInterval, precision);
|
|
// If the interval is not big enough in the current min - max range
|
|
// to actually increase the loop variable, we need to break out to
|
|
// prevent endless loop. Issue #619
|
|
if (pos === lastPos) {
|
|
break;
|
|
}
|
|
// Record the last value
|
|
lastPos = pos;
|
|
}
|
|
return tickPositions;
|
|
};
|
|
/**
|
|
* Resolve the new minorTicks/minorTickInterval options into the legacy
|
|
* loosely typed minorTickInterval option.
|
|
*
|
|
* @function Highcharts.Axis#getMinorTickInterval
|
|
*
|
|
* @return {number|"auto"|null}
|
|
*/
|
|
Axis.prototype.getMinorTickInterval = function () {
|
|
var options = this.options;
|
|
if (options.minorTicks === true) {
|
|
return pick(options.minorTickInterval, 'auto');
|
|
}
|
|
if (options.minorTicks === false) {
|
|
return null;
|
|
}
|
|
return options.minorTickInterval;
|
|
};
|
|
/**
|
|
* Internal function to return the minor tick positions. For logarithmic
|
|
* axes, the same logic as for major ticks is reused.
|
|
*
|
|
* @function Highcharts.Axis#getMinorTickPositions
|
|
*
|
|
* @return {Array<number>}
|
|
* An array of axis values where ticks should be placed.
|
|
*/
|
|
Axis.prototype.getMinorTickPositions = function () {
|
|
var axis = this, options = axis.options, tickPositions = axis.tickPositions, minorTickInterval = axis.minorTickInterval, minorTickPositions = [], pos, pointRangePadding = axis.pointRangePadding || 0, min = axis.min - pointRangePadding, // #1498
|
|
max = axis.max + pointRangePadding, // #1498
|
|
range = max - min;
|
|
// If minor ticks get too dense, they are hard to read, and may cause
|
|
// long running script. So we don't draw them.
|
|
if (range && range / minorTickInterval < axis.len / 3) { // #3875
|
|
var logarithmic_1 = axis.logarithmic;
|
|
if (logarithmic_1) {
|
|
// For each interval in the major ticks, compute the minor ticks
|
|
// separately.
|
|
this.paddedTicks.forEach(function (_pos, i, paddedTicks) {
|
|
if (i) {
|
|
minorTickPositions.push.apply(minorTickPositions, logarithmic_1.getLogTickPositions(minorTickInterval, paddedTicks[i - 1], paddedTicks[i], true));
|
|
}
|
|
});
|
|
}
|
|
else if (axis.dateTime &&
|
|
this.getMinorTickInterval() === 'auto') { // #1314
|
|
minorTickPositions = minorTickPositions.concat(axis.getTimeTicks(axis.dateTime.normalizeTimeTickInterval(minorTickInterval), min, max, options.startOfWeek));
|
|
}
|
|
else {
|
|
for (pos = min + (tickPositions[0] - min) % minorTickInterval; pos <= max; pos += minorTickInterval) {
|
|
// Very, very, tight grid lines (#5771)
|
|
if (pos === minorTickPositions[0]) {
|
|
break;
|
|
}
|
|
minorTickPositions.push(pos);
|
|
}
|
|
}
|
|
}
|
|
if (minorTickPositions.length !== 0) {
|
|
axis.trimTicks(minorTickPositions); // #3652 #3743 #1498 #6330
|
|
}
|
|
return minorTickPositions;
|
|
};
|
|
/**
|
|
* Adjust the min and max for the minimum range. Keep in mind that the
|
|
* series data is not yet processed, so we don't have information on data
|
|
* cropping and grouping, or updated `axis.pointRange` or
|
|
* `series.pointRange`. The data can't be processed until we have finally
|
|
* established min and max.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#adjustForMinRange
|
|
*/
|
|
Axis.prototype.adjustForMinRange = function () {
|
|
var axis = this, options = axis.options, min = axis.min, max = axis.max, log = axis.logarithmic, zoomOffset, spaceAvailable, closestDataRange, i, distance, xData, loopLength, minArgs, maxArgs, minRange;
|
|
// Set the automatic minimum range based on the closest point distance
|
|
if (axis.isXAxis &&
|
|
typeof axis.minRange === 'undefined' &&
|
|
!log) {
|
|
if (defined(options.min) || defined(options.max)) {
|
|
axis.minRange = null; // don't do this again
|
|
}
|
|
else {
|
|
// Find the closest distance between raw data points, as opposed
|
|
// to closestPointRange that applies to processed points
|
|
// (cropped and grouped)
|
|
axis.series.forEach(function (series) {
|
|
xData = series.xData;
|
|
loopLength = series.xIncrement ? 1 : xData.length - 1;
|
|
for (i = loopLength; i > 0; i--) {
|
|
distance = xData[i] - xData[i - 1];
|
|
if (typeof closestDataRange === 'undefined' ||
|
|
distance < closestDataRange) {
|
|
closestDataRange = distance;
|
|
}
|
|
}
|
|
});
|
|
axis.minRange = Math.min(closestDataRange * 5, axis.dataMax - axis.dataMin);
|
|
}
|
|
}
|
|
// if minRange is exceeded, adjust
|
|
if (max - min < axis.minRange) {
|
|
spaceAvailable =
|
|
axis.dataMax - axis.dataMin >=
|
|
axis.minRange;
|
|
minRange = axis.minRange;
|
|
zoomOffset = (minRange - max + min) / 2;
|
|
// if min and max options have been set, don't go beyond it
|
|
minArgs = [
|
|
min - zoomOffset,
|
|
pick(options.min, min - zoomOffset)
|
|
];
|
|
// If space is available, stay within the data range
|
|
if (spaceAvailable) {
|
|
minArgs[2] = axis.logarithmic ?
|
|
axis.logarithmic.log2lin(axis.dataMin) :
|
|
axis.dataMin;
|
|
}
|
|
min = arrayMax(minArgs);
|
|
maxArgs = [
|
|
min + minRange,
|
|
pick(options.max, min + minRange)
|
|
];
|
|
// If space is availabe, stay within the data range
|
|
if (spaceAvailable) {
|
|
maxArgs[2] = log ?
|
|
log.log2lin(axis.dataMax) :
|
|
axis.dataMax;
|
|
}
|
|
max = arrayMin(maxArgs);
|
|
// now if the max is adjusted, adjust the min back
|
|
if (max - min < minRange) {
|
|
minArgs[0] = max - minRange;
|
|
minArgs[1] = pick(options.min, max - minRange);
|
|
min = arrayMax(minArgs);
|
|
}
|
|
}
|
|
// Record modified extremes
|
|
axis.min = min;
|
|
axis.max = max;
|
|
};
|
|
// eslint-disable-next-line valid-jsdoc
|
|
/**
|
|
* Find the closestPointRange across all series.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#getClosest
|
|
*/
|
|
Axis.prototype.getClosest = function () {
|
|
var ret;
|
|
if (this.categories) {
|
|
ret = 1;
|
|
}
|
|
else {
|
|
this.series.forEach(function (series) {
|
|
var seriesClosest = series.closestPointRange, visible = series.visible ||
|
|
!series.chart.options.chart.ignoreHiddenSeries;
|
|
if (!series.noSharedTooltip &&
|
|
defined(seriesClosest) &&
|
|
visible) {
|
|
ret = defined(ret) ?
|
|
Math.min(ret, seriesClosest) :
|
|
seriesClosest;
|
|
}
|
|
});
|
|
}
|
|
return ret;
|
|
};
|
|
/**
|
|
* When a point name is given and no x, search for the name in the existing
|
|
* categories, or if categories aren't provided, search names or create a
|
|
* new category (#2522).
|
|
* @private
|
|
* @function Highcharts.Axis#nameToX
|
|
*
|
|
* @param {Highcharts.Point} point
|
|
* The point to inspect.
|
|
*
|
|
* @return {number}
|
|
* The X value that the point is given.
|
|
*/
|
|
Axis.prototype.nameToX = function (point) {
|
|
var explicitCategories = isArray(this.categories), names = explicitCategories ? this.categories : this.names, nameX = point.options.x, x;
|
|
point.series.requireSorting = false;
|
|
if (!defined(nameX)) {
|
|
nameX = this.options.uniqueNames === false ?
|
|
point.series.autoIncrement() :
|
|
(explicitCategories ?
|
|
names.indexOf(point.name) :
|
|
pick(names.keys[point.name], -1));
|
|
}
|
|
if (nameX === -1) { // Not found in currenct categories
|
|
if (!explicitCategories) {
|
|
x = names.length;
|
|
}
|
|
}
|
|
else {
|
|
x = nameX;
|
|
}
|
|
// Write the last point's name to the names array
|
|
if (typeof x !== 'undefined') {
|
|
this.names[x] = point.name;
|
|
// Backwards mapping is much faster than array searching (#7725)
|
|
this.names.keys[point.name] = x;
|
|
}
|
|
return x;
|
|
};
|
|
/**
|
|
* When changes have been done to series data, update the axis.names.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#updateNames
|
|
*/
|
|
Axis.prototype.updateNames = function () {
|
|
var axis = this, names = this.names, i = names.length;
|
|
if (i > 0) {
|
|
Object.keys(names.keys).forEach(function (key) {
|
|
delete (names.keys)[key];
|
|
});
|
|
names.length = 0;
|
|
this.minRange = this.userMinRange; // Reset
|
|
(this.series || []).forEach(function (series) {
|
|
// Reset incrementer (#5928)
|
|
series.xIncrement = null;
|
|
// When adding a series, points are not yet generated
|
|
if (!series.points || series.isDirtyData) {
|
|
// When we're updating the series with data that is longer
|
|
// than it was, and cropThreshold is passed, we need to make
|
|
// sure that the axis.max is increased _before_ running the
|
|
// premature processData. Otherwise this early iteration of
|
|
// processData will crop the points to axis.max, and the
|
|
// names array will be too short (#5857).
|
|
axis.max = Math.max(axis.max, series.xData.length - 1);
|
|
series.processData();
|
|
series.generatePoints();
|
|
}
|
|
series.data.forEach(function (point, i) {
|
|
var x;
|
|
if (point &&
|
|
point.options &&
|
|
typeof point.name !== 'undefined' // #9562
|
|
) {
|
|
x = axis.nameToX(point);
|
|
if (typeof x !== 'undefined' && x !== point.x) {
|
|
point.x = x;
|
|
series.xData[i] = x;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
};
|
|
/**
|
|
* Update translation information.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#setAxisTranslation
|
|
*
|
|
* @param {boolean} [saveOld]
|
|
* TO-DO: parameter description
|
|
*
|
|
* @fires Highcharts.Axis#event:afterSetAxisTranslation
|
|
*/
|
|
Axis.prototype.setAxisTranslation = function (saveOld) {
|
|
var axis = this, range = axis.max - axis.min, pointRange = axis.axisPointRange || 0, closestPointRange, minPointOffset = 0, pointRangePadding = 0, linkedParent = axis.linkedParent, ordinalCorrection, hasCategories = !!axis.categories, transA = axis.transA, isXAxis = axis.isXAxis;
|
|
// Adjust translation for padding. Y axis with categories need to go
|
|
// through the same (#1784).
|
|
if (isXAxis || hasCategories || pointRange) {
|
|
// Get the closest points
|
|
closestPointRange = axis.getClosest();
|
|
if (linkedParent) {
|
|
minPointOffset = linkedParent.minPointOffset;
|
|
pointRangePadding = linkedParent.pointRangePadding;
|
|
}
|
|
else {
|
|
axis.series.forEach(function (series) {
|
|
var seriesPointRange = hasCategories ?
|
|
1 :
|
|
(isXAxis ?
|
|
pick(series.options.pointRange, closestPointRange, 0) :
|
|
(axis.axisPointRange || 0)), // #2806
|
|
pointPlacement = series.options.pointPlacement;
|
|
pointRange = Math.max(pointRange, seriesPointRange);
|
|
if (!axis.single || hasCategories) {
|
|
// TODO: series should internally set x- and y-
|
|
// pointPlacement to simplify this logic.
|
|
var isPointPlacementAxis = series.is('xrange') ? !isXAxis : isXAxis;
|
|
// minPointOffset is the value padding to the left of
|
|
// the axis in order to make room for points with a
|
|
// pointRange, typically columns. When the
|
|
// pointPlacement option is 'between' or 'on', this
|
|
// padding does not apply.
|
|
minPointOffset = Math.max(minPointOffset, isPointPlacementAxis && isString(pointPlacement) ?
|
|
0 :
|
|
seriesPointRange / 2);
|
|
// Determine the total padding needed to the length of
|
|
// the axis to make room for the pointRange. If the
|
|
// series' pointPlacement is 'on', no padding is added.
|
|
pointRangePadding = Math.max(pointRangePadding, isPointPlacementAxis && pointPlacement === 'on' ?
|
|
0 :
|
|
seriesPointRange);
|
|
}
|
|
});
|
|
}
|
|
// Record minPointOffset and pointRangePadding
|
|
ordinalCorrection = axis.ordinal && axis.ordinal.slope && closestPointRange ?
|
|
axis.ordinal.slope / closestPointRange :
|
|
1; // #988, #1853
|
|
axis.minPointOffset = minPointOffset =
|
|
minPointOffset * ordinalCorrection;
|
|
axis.pointRangePadding =
|
|
pointRangePadding = pointRangePadding * ordinalCorrection;
|
|
// pointRange means the width reserved for each point, like in a
|
|
// column chart
|
|
axis.pointRange = Math.min(pointRange, axis.single && hasCategories ? 1 : range);
|
|
// closestPointRange means the closest distance between points. In
|
|
// columns it is mostly equal to pointRange, but in lines pointRange
|
|
// is 0 while closestPointRange is some other value
|
|
if (isXAxis) {
|
|
axis.closestPointRange = closestPointRange;
|
|
}
|
|
}
|
|
// Secondary values
|
|
if (saveOld) {
|
|
axis.oldTransA = transA;
|
|
}
|
|
axis.translationSlope = axis.transA = transA =
|
|
axis.staticScale ||
|
|
axis.len / ((range + pointRangePadding) || 1);
|
|
// Translation addend
|
|
axis.transB = axis.horiz ? axis.left : axis.bottom;
|
|
axis.minPixelPadding = transA * minPointOffset;
|
|
fireEvent(this, 'afterSetAxisTranslation');
|
|
};
|
|
/**
|
|
* @private
|
|
* @function Highcharts.Axis#minFromRange
|
|
*
|
|
* @return {number}
|
|
*/
|
|
Axis.prototype.minFromRange = function () {
|
|
var axis = this;
|
|
return axis.max - axis.range;
|
|
};
|
|
/**
|
|
* Set the tick positions to round values and optionally extend the extremes
|
|
* to the nearest tick.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#setTickInterval
|
|
*
|
|
* @param {boolean} secondPass
|
|
* TO-DO: parameter description
|
|
*
|
|
* @fires Highcharts.Axis#event:foundExtremes
|
|
*/
|
|
Axis.prototype.setTickInterval = function (secondPass) {
|
|
var axis = this, chart = axis.chart, log = axis.logarithmic, options = axis.options, isXAxis = axis.isXAxis, isLinked = axis.isLinked, maxPadding = options.maxPadding, minPadding = options.minPadding, length, linkedParentExtremes, tickIntervalOption = options.tickInterval, minTickInterval, tickPixelIntervalOption = options.tickPixelInterval, categories = axis.categories, threshold = isNumber(axis.threshold) ? axis.threshold : null, softThreshold = axis.softThreshold, thresholdMin, thresholdMax, hardMin, hardMax;
|
|
if (!axis.dateTime && !categories && !isLinked) {
|
|
this.getTickAmount();
|
|
}
|
|
// Min or max set either by zooming/setExtremes or initial options
|
|
hardMin = pick(axis.userMin, options.min);
|
|
hardMax = pick(axis.userMax, options.max);
|
|
// Linked axis gets the extremes from the parent axis
|
|
if (isLinked) {
|
|
axis.linkedParent = chart[axis.coll][options.linkedTo];
|
|
linkedParentExtremes = axis.linkedParent.getExtremes();
|
|
axis.min = pick(linkedParentExtremes.min, linkedParentExtremes.dataMin);
|
|
axis.max = pick(linkedParentExtremes.max, linkedParentExtremes.dataMax);
|
|
if (options.type !== axis.linkedParent.options.type) {
|
|
// Can't link axes of different type
|
|
error(11, 1, chart);
|
|
}
|
|
// Initial min and max from the extreme data values
|
|
}
|
|
else {
|
|
// Adjust to hard threshold
|
|
if (!softThreshold && defined(threshold)) {
|
|
if (axis.dataMin >= threshold) {
|
|
thresholdMin = threshold;
|
|
minPadding = 0;
|
|
}
|
|
else if (axis.dataMax <= threshold) {
|
|
thresholdMax = threshold;
|
|
maxPadding = 0;
|
|
}
|
|
}
|
|
axis.min = pick(hardMin, thresholdMin, axis.dataMin);
|
|
axis.max = pick(hardMax, thresholdMax, axis.dataMax);
|
|
}
|
|
if (log) {
|
|
if (axis.positiveValuesOnly &&
|
|
!secondPass &&
|
|
Math.min(axis.min, pick(axis.dataMin, axis.min)) <= 0) { // #978
|
|
// Can't plot negative values on log axis
|
|
error(10, 1, chart);
|
|
}
|
|
// The correctFloat cures #934, float errors on full tens. But it
|
|
// was too aggressive for #4360 because of conversion back to lin,
|
|
// therefore use precision 15.
|
|
axis.min = correctFloat(log.log2lin(axis.min), 16);
|
|
axis.max = correctFloat(log.log2lin(axis.max), 16);
|
|
}
|
|
// handle zoomed range
|
|
if (axis.range && defined(axis.max)) {
|
|
// #618, #6773:
|
|
axis.userMin = axis.min = hardMin =
|
|
Math.max(axis.dataMin, axis.minFromRange());
|
|
axis.userMax = hardMax = axis.max;
|
|
axis.range = null; // don't use it when running setExtremes
|
|
}
|
|
// Hook for Highstock Scroller. Consider combining with beforePadding.
|
|
fireEvent(axis, 'foundExtremes');
|
|
// Hook for adjusting this.min and this.max. Used by bubble series.
|
|
if (axis.beforePadding) {
|
|
axis.beforePadding();
|
|
}
|
|
// adjust min and max for the minimum range
|
|
axis.adjustForMinRange();
|
|
// Pad the values to get clear of the chart's edges. To avoid
|
|
// tickInterval taking the padding into account, we do this after
|
|
// computing tick interval (#1337).
|
|
if (!categories &&
|
|
!axis.axisPointRange &&
|
|
!(axis.stacking && axis.stacking.usePercentage) &&
|
|
!isLinked &&
|
|
defined(axis.min) &&
|
|
defined(axis.max)) {
|
|
length = axis.max - axis.min;
|
|
if (length) {
|
|
if (!defined(hardMin) && minPadding) {
|
|
axis.min -= length * minPadding;
|
|
}
|
|
if (!defined(hardMax) && maxPadding) {
|
|
axis.max += length * maxPadding;
|
|
}
|
|
}
|
|
}
|
|
// Handle options for floor, ceiling, softMin and softMax (#6359)
|
|
if (!isNumber(axis.userMin)) {
|
|
if (isNumber(options.softMin) && options.softMin < axis.min) {
|
|
axis.min = hardMin = options.softMin; // #6894
|
|
}
|
|
if (isNumber(options.floor)) {
|
|
axis.min = Math.max(axis.min, options.floor);
|
|
}
|
|
}
|
|
if (!isNumber(axis.userMax)) {
|
|
if (isNumber(options.softMax) && options.softMax > axis.max) {
|
|
axis.max = hardMax = options.softMax; // #6894
|
|
}
|
|
if (isNumber(options.ceiling)) {
|
|
axis.max = Math.min(axis.max, options.ceiling);
|
|
}
|
|
}
|
|
// When the threshold is soft, adjust the extreme value only if the data
|
|
// extreme and the padded extreme land on either side of the threshold.
|
|
// For example, a series of [0, 1, 2, 3] would make the yAxis add a tick
|
|
// for -1 because of the default minPadding and startOnTick options.
|
|
// This is prevented by the softThreshold option.
|
|
if (softThreshold && defined(axis.dataMin)) {
|
|
threshold = threshold || 0;
|
|
if (!defined(hardMin) &&
|
|
axis.min < threshold &&
|
|
axis.dataMin >= threshold) {
|
|
axis.min = axis.options.minRange ?
|
|
Math.min(threshold, axis.max -
|
|
axis.minRange) :
|
|
threshold;
|
|
}
|
|
else if (!defined(hardMax) &&
|
|
axis.max > threshold &&
|
|
axis.dataMax <= threshold) {
|
|
axis.max = axis.options.minRange ?
|
|
Math.max(threshold, axis.min +
|
|
axis.minRange) :
|
|
threshold;
|
|
}
|
|
}
|
|
// get tickInterval
|
|
if (axis.min === axis.max ||
|
|
typeof axis.min === 'undefined' ||
|
|
typeof axis.max === 'undefined') {
|
|
axis.tickInterval = 1;
|
|
}
|
|
else if (isLinked &&
|
|
!tickIntervalOption &&
|
|
tickPixelIntervalOption ===
|
|
axis.linkedParent.options.tickPixelInterval) {
|
|
axis.tickInterval = tickIntervalOption =
|
|
axis.linkedParent.tickInterval;
|
|
}
|
|
else {
|
|
axis.tickInterval = pick(tickIntervalOption, this.tickAmount ?
|
|
((axis.max - axis.min) /
|
|
Math.max(this.tickAmount - 1, 1)) :
|
|
void 0,
|
|
// For categoried axis, 1 is default, for linear axis use
|
|
// tickPix
|
|
categories ?
|
|
1 :
|
|
// don't let it be more than the data range
|
|
(axis.max - axis.min) *
|
|
tickPixelIntervalOption /
|
|
Math.max(axis.len, tickPixelIntervalOption));
|
|
}
|
|
// Now we're finished detecting min and max, crop and group series data.
|
|
// This is in turn needed in order to find tick positions in ordinal
|
|
// axes.
|
|
if (isXAxis && !secondPass) {
|
|
axis.series.forEach(function (series) {
|
|
series.processData(axis.min !== axis.oldMin || axis.max !== axis.oldMax);
|
|
});
|
|
}
|
|
// set the translation factor used in translate function
|
|
axis.setAxisTranslation(true);
|
|
// hook for ordinal axes and radial axes
|
|
if (axis.beforeSetTickPositions) {
|
|
axis.beforeSetTickPositions();
|
|
}
|
|
// hook for extensions, used in Highstock ordinal axes
|
|
if (axis.ordinal) {
|
|
axis.tickInterval = axis.ordinal.postProcessTickInterval(axis.tickInterval);
|
|
}
|
|
// In column-like charts, don't cramp in more ticks than there are
|
|
// points (#1943, #4184)
|
|
if (axis.pointRange && !tickIntervalOption) {
|
|
axis.tickInterval = Math.max(axis.pointRange, axis.tickInterval);
|
|
}
|
|
// Before normalizing the tick interval, handle minimum tick interval.
|
|
// This applies only if tickInterval is not defined.
|
|
minTickInterval = pick(options.minTickInterval, (axis.dateTime && axis.closestPointRange));
|
|
if (!tickIntervalOption && axis.tickInterval < minTickInterval) {
|
|
axis.tickInterval = minTickInterval;
|
|
}
|
|
// for linear axes, get magnitude and normalize the interval
|
|
if (!axis.dateTime && !axis.logarithmic && !tickIntervalOption) {
|
|
axis.tickInterval = normalizeTickInterval(axis.tickInterval, void 0, getMagnitude(axis.tickInterval), pick(options.allowDecimals,
|
|
// If the tick interval is greather than 0.5, avoid
|
|
// decimals, as linear axes are often used to render
|
|
// discrete values. #3363. If a tick amount is set, allow
|
|
// decimals by default, as it increases the chances for a
|
|
// good fit.
|
|
axis.tickInterval < 0.5 || this.tickAmount !== void 0), !!this.tickAmount);
|
|
}
|
|
// Prevent ticks from getting so close that we can't draw the labels
|
|
if (!this.tickAmount) {
|
|
axis.tickInterval = axis.unsquish();
|
|
}
|
|
this.setTickPositions();
|
|
};
|
|
/**
|
|
* Now we have computed the normalized tickInterval, get the tick positions
|
|
*
|
|
* @function Highcharts.Axis#setTickPositions
|
|
*
|
|
* @fires Highcharts.Axis#event:afterSetTickPositions
|
|
*/
|
|
Axis.prototype.setTickPositions = function () {
|
|
var axis = this, options = this.options, tickPositions, tickPositionsOption = options.tickPositions, minorTickIntervalOption = this.getMinorTickInterval(), tickPositioner = options.tickPositioner, hasVerticalPanning = this.hasVerticalPanning(), isColorAxis = this.coll === 'colorAxis', startOnTick = (isColorAxis || !hasVerticalPanning) && options.startOnTick, endOnTick = (isColorAxis || !hasVerticalPanning) && options.endOnTick;
|
|
// Set the tickmarkOffset
|
|
this.tickmarkOffset = (this.categories &&
|
|
options.tickmarkPlacement === 'between' &&
|
|
this.tickInterval === 1) ? 0.5 : 0; // #3202
|
|
// get minorTickInterval
|
|
this.minorTickInterval =
|
|
minorTickIntervalOption === 'auto' &&
|
|
this.tickInterval ?
|
|
this.tickInterval / 5 :
|
|
minorTickIntervalOption;
|
|
// When there is only one point, or all points have the same value on
|
|
// this axis, then min and max are equal and tickPositions.length is 0
|
|
// or 1. In this case, add some padding in order to center the point,
|
|
// but leave it with one tick. #1337.
|
|
this.single =
|
|
this.min === this.max &&
|
|
defined(this.min) &&
|
|
!this.tickAmount &&
|
|
(
|
|
// Data is on integer (#6563)
|
|
parseInt(this.min, 10) === this.min ||
|
|
// Between integers and decimals are not allowed (#6274)
|
|
options.allowDecimals !== false);
|
|
/**
|
|
* Contains the current positions that are laid out on the axis. The
|
|
* positions are numbers in terms of axis values. In a category axis
|
|
* they are integers, in a datetime axis they are also integers, but
|
|
* designating milliseconds.
|
|
*
|
|
* This property is read only - for modifying the tick positions, use
|
|
* the `tickPositioner` callback or [axis.tickPositions(
|
|
* https://api.highcharts.com/highcharts/xAxis.tickPositions) option
|
|
* instead.
|
|
*
|
|
* @name Highcharts.Axis#tickPositions
|
|
* @type {Highcharts.AxisTickPositionsArray|undefined}
|
|
*/
|
|
this.tickPositions =
|
|
// Find the tick positions. Work on a copy (#1565)
|
|
tickPositions =
|
|
(tickPositionsOption && tickPositionsOption.slice());
|
|
if (!tickPositions) {
|
|
// Too many ticks (#6405). Create a friendly warning and provide two
|
|
// ticks so at least we can show the data series.
|
|
if ((!axis.ordinal || !axis.ordinal.positions) &&
|
|
((this.max - this.min) /
|
|
this.tickInterval >
|
|
Math.max(2 * this.len, 200))) {
|
|
tickPositions = [this.min, this.max];
|
|
error(19, false, this.chart);
|
|
}
|
|
else if (axis.dateTime) {
|
|
tickPositions = axis.getTimeTicks(axis.dateTime.normalizeTimeTickInterval(this.tickInterval, options.units), this.min, this.max, options.startOfWeek, axis.ordinal && axis.ordinal.positions, this.closestPointRange, true);
|
|
}
|
|
else if (axis.logarithmic) {
|
|
tickPositions = axis.logarithmic.getLogTickPositions(this.tickInterval, this.min, this.max);
|
|
}
|
|
else {
|
|
tickPositions = this.getLinearTickPositions(this.tickInterval, this.min, this.max);
|
|
}
|
|
// Too dense ticks, keep only the first and last (#4477)
|
|
if (tickPositions.length > this.len) {
|
|
tickPositions = [tickPositions[0], tickPositions.pop()];
|
|
// Reduce doubled value (#7339)
|
|
if (tickPositions[0] === tickPositions[1]) {
|
|
tickPositions.length = 1;
|
|
}
|
|
}
|
|
this.tickPositions = tickPositions;
|
|
// Run the tick positioner callback, that allows modifying auto tick
|
|
// positions.
|
|
if (tickPositioner) {
|
|
tickPositioner = tickPositioner.apply(axis, [this.min, this.max]);
|
|
if (tickPositioner) {
|
|
this.tickPositions = tickPositions = tickPositioner;
|
|
}
|
|
}
|
|
}
|
|
// Reset min/max or remove extremes based on start/end on tick
|
|
this.paddedTicks = tickPositions.slice(0); // Used for logarithmic minor
|
|
this.trimTicks(tickPositions, startOnTick, endOnTick);
|
|
if (!this.isLinked) {
|
|
// Substract half a unit (#2619, #2846, #2515, #3390),
|
|
// but not in case of multiple ticks (#6897)
|
|
if (this.single &&
|
|
tickPositions.length < 2 &&
|
|
!this.categories &&
|
|
!this.series.some(function (s) {
|
|
return (s.is('heatmap') && s.options.pointPlacement === 'between');
|
|
})) {
|
|
this.min -= 0.5;
|
|
this.max += 0.5;
|
|
}
|
|
if (!tickPositionsOption && !tickPositioner) {
|
|
this.adjustTickAmount();
|
|
}
|
|
}
|
|
fireEvent(this, 'afterSetTickPositions');
|
|
};
|
|
/**
|
|
* Handle startOnTick and endOnTick by either adapting to padding min/max or
|
|
* rounded min/max. Also handle single data points.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#trimTicks
|
|
*
|
|
* @param {Array<number>} tickPositions
|
|
* TO-DO: parameter description
|
|
*
|
|
* @param {boolean} [startOnTick]
|
|
* TO-DO: parameter description
|
|
*
|
|
* @param {boolean} [endOnTick]
|
|
* TO-DO: parameter description
|
|
*/
|
|
Axis.prototype.trimTicks = function (tickPositions, startOnTick, endOnTick) {
|
|
var roundedMin = tickPositions[0], roundedMax = tickPositions[tickPositions.length - 1], minPointOffset = (!this.isOrdinal && this.minPointOffset) || 0; // (#12716)
|
|
fireEvent(this, 'trimTicks');
|
|
if (!this.isLinked) {
|
|
if (startOnTick && roundedMin !== -Infinity) { // #6502
|
|
this.min = roundedMin;
|
|
}
|
|
else {
|
|
while (this.min - minPointOffset > tickPositions[0]) {
|
|
tickPositions.shift();
|
|
}
|
|
}
|
|
if (endOnTick) {
|
|
this.max = roundedMax;
|
|
}
|
|
else {
|
|
while (this.max + minPointOffset <
|
|
tickPositions[tickPositions.length - 1]) {
|
|
tickPositions.pop();
|
|
}
|
|
}
|
|
// If no tick are left, set one tick in the middle (#3195)
|
|
if (tickPositions.length === 0 &&
|
|
defined(roundedMin) &&
|
|
!this.options.tickPositions) {
|
|
tickPositions.push((roundedMax + roundedMin) / 2);
|
|
}
|
|
}
|
|
};
|
|
/**
|
|
* Check if there are multiple axes in the same pane.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#alignToOthers
|
|
*
|
|
* @return {boolean|undefined}
|
|
* True if there are other axes.
|
|
*/
|
|
Axis.prototype.alignToOthers = function () {
|
|
var axis = this, others = // Whether there is another axis to pair with this one
|
|
{}, hasOther, options = axis.options;
|
|
if (
|
|
// Only if alignTicks is true
|
|
this.chart.options.chart.alignTicks !== false &&
|
|
options.alignTicks !== false &&
|
|
// Disabled when startOnTick or endOnTick are false (#7604)
|
|
options.startOnTick !== false &&
|
|
options.endOnTick !== false &&
|
|
// Don't try to align ticks on a log axis, they are not evenly
|
|
// spaced (#6021)
|
|
!axis.logarithmic) {
|
|
this.chart[this.coll].forEach(function (axis) {
|
|
var otherOptions = axis.options, horiz = axis.horiz, key = [
|
|
horiz ? otherOptions.left : otherOptions.top,
|
|
otherOptions.width,
|
|
otherOptions.height,
|
|
otherOptions.pane
|
|
].join(',');
|
|
if (axis.series.length) { // #4442
|
|
if (others[key]) {
|
|
hasOther = true; // #4201
|
|
}
|
|
else {
|
|
others[key] = 1;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
return hasOther;
|
|
};
|
|
/**
|
|
* Find the max ticks of either the x and y axis collection, and record it
|
|
* in `this.tickAmount`.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#getTickAmount
|
|
*/
|
|
Axis.prototype.getTickAmount = function () {
|
|
var axis = this, options = this.options, tickAmount = options.tickAmount, tickPixelInterval = options.tickPixelInterval;
|
|
if (!defined(options.tickInterval) &&
|
|
!tickAmount && this.len < tickPixelInterval &&
|
|
!this.isRadial &&
|
|
!axis.logarithmic &&
|
|
options.startOnTick &&
|
|
options.endOnTick) {
|
|
tickAmount = 2;
|
|
}
|
|
if (!tickAmount && this.alignToOthers()) {
|
|
// Add 1 because 4 tick intervals require 5 ticks (including first
|
|
// and last)
|
|
tickAmount = Math.ceil(this.len / tickPixelInterval) + 1;
|
|
}
|
|
// For tick amounts of 2 and 3, compute five ticks and remove the
|
|
// intermediate ones. This prevents the axis from adding ticks that are
|
|
// too far away from the data extremes.
|
|
if (tickAmount < 4) {
|
|
this.finalTickAmt = tickAmount;
|
|
tickAmount = 5;
|
|
}
|
|
this.tickAmount = tickAmount;
|
|
};
|
|
/**
|
|
* When using multiple axes, adjust the number of ticks to match the highest
|
|
* number of ticks in that group.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#adjustTickAmount
|
|
*/
|
|
Axis.prototype.adjustTickAmount = function () {
|
|
var axis = this, axisOptions = axis.options, tickInterval = axis.tickInterval, tickPositions = axis.tickPositions, tickAmount = axis.tickAmount, finalTickAmt = axis.finalTickAmt, currentTickAmount = tickPositions && tickPositions.length, threshold = pick(axis.threshold, axis.softThreshold ? 0 : null), min, len, i;
|
|
if (axis.hasData()) {
|
|
if (currentTickAmount < tickAmount) {
|
|
min = axis.min;
|
|
while (tickPositions.length < tickAmount) {
|
|
// Extend evenly for both sides unless we're on the
|
|
// threshold (#3965)
|
|
if (tickPositions.length % 2 ||
|
|
min === threshold) {
|
|
// to the end
|
|
tickPositions.push(correctFloat(tickPositions[tickPositions.length - 1] +
|
|
tickInterval));
|
|
}
|
|
else {
|
|
// to the start
|
|
tickPositions.unshift(correctFloat(tickPositions[0] - tickInterval));
|
|
}
|
|
}
|
|
axis.transA *= (currentTickAmount - 1) / (tickAmount - 1);
|
|
// Do not crop when ticks are not extremes (#9841)
|
|
axis.min = axisOptions.startOnTick ?
|
|
tickPositions[0] :
|
|
Math.min(axis.min, tickPositions[0]);
|
|
axis.max = axisOptions.endOnTick ?
|
|
tickPositions[tickPositions.length - 1] :
|
|
Math.max(axis.max, tickPositions[tickPositions.length - 1]);
|
|
// We have too many ticks, run second pass to try to reduce ticks
|
|
}
|
|
else if (currentTickAmount > tickAmount) {
|
|
axis.tickInterval *= 2;
|
|
axis.setTickPositions();
|
|
}
|
|
// The finalTickAmt property is set in getTickAmount
|
|
if (defined(finalTickAmt)) {
|
|
i = len = tickPositions.length;
|
|
while (i--) {
|
|
if (
|
|
// Remove every other tick
|
|
(finalTickAmt === 3 && i % 2 === 1) ||
|
|
// Remove all but first and last
|
|
(finalTickAmt <= 2 && i > 0 && i < len - 1)) {
|
|
tickPositions.splice(i, 1);
|
|
}
|
|
}
|
|
axis.finalTickAmt = void 0;
|
|
}
|
|
}
|
|
};
|
|
/**
|
|
* Set the scale based on data min and max, user set min and max or options.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#setScale
|
|
*
|
|
* @fires Highcharts.Axis#event:afterSetScale
|
|
*/
|
|
Axis.prototype.setScale = function () {
|
|
var axis = this, isDirtyAxisLength, isDirtyData = false, isXAxisDirty = false;
|
|
axis.series.forEach(function (series) {
|
|
var _a;
|
|
isDirtyData = isDirtyData || series.isDirtyData || series.isDirty;
|
|
// When x axis is dirty, we need new data extremes for y as
|
|
// well:
|
|
isXAxisDirty = isXAxisDirty || ((_a = series.xAxis) === null || _a === void 0 ? void 0 : _a.isDirty) || false;
|
|
});
|
|
axis.oldMin = axis.min;
|
|
axis.oldMax = axis.max;
|
|
axis.oldAxisLength = axis.len;
|
|
// set the new axisLength
|
|
axis.setAxisSize();
|
|
isDirtyAxisLength = axis.len !== axis.oldAxisLength;
|
|
// do we really need to go through all this?
|
|
if (isDirtyAxisLength ||
|
|
isDirtyData ||
|
|
isXAxisDirty ||
|
|
axis.isLinked ||
|
|
axis.forceRedraw ||
|
|
axis.userMin !== axis.oldUserMin ||
|
|
axis.userMax !== axis.oldUserMax ||
|
|
axis.alignToOthers()) {
|
|
if (axis.stacking) {
|
|
axis.stacking.resetStacks();
|
|
}
|
|
axis.forceRedraw = false;
|
|
// get data extremes if needed
|
|
axis.getSeriesExtremes();
|
|
// get fixed positions based on tickInterval
|
|
axis.setTickInterval();
|
|
// record old values to decide whether a rescale is necessary later
|
|
// on (#540)
|
|
axis.oldUserMin = axis.userMin;
|
|
axis.oldUserMax = axis.userMax;
|
|
// Mark as dirty if it is not already set to dirty and extremes have
|
|
// changed. #595.
|
|
if (!axis.isDirty) {
|
|
axis.isDirty =
|
|
isDirtyAxisLength ||
|
|
axis.min !== axis.oldMin ||
|
|
axis.max !== axis.oldMax;
|
|
}
|
|
}
|
|
else if (axis.stacking) {
|
|
axis.stacking.cleanStacks();
|
|
}
|
|
// Recalculate panning state object, when the data
|
|
// has changed. It is required when vertical panning is enabled.
|
|
if (isDirtyData && axis.panningState) {
|
|
axis.panningState.isDirty = true;
|
|
}
|
|
fireEvent(this, 'afterSetScale');
|
|
};
|
|
/**
|
|
* Set the minimum and maximum of the axes after render time. If the
|
|
* `startOnTick` and `endOnTick` options are true, the minimum and maximum
|
|
* values are rounded off to the nearest tick. To prevent this, these
|
|
* options can be set to false before calling setExtremes. Also, setExtremes
|
|
* will not allow a range lower than the `minRange` option, which by default
|
|
* is the range of five points.
|
|
*
|
|
* @sample highcharts/members/axis-setextremes/
|
|
* Set extremes from a button
|
|
* @sample highcharts/members/axis-setextremes-datetime/
|
|
* Set extremes on a datetime axis
|
|
* @sample highcharts/members/axis-setextremes-off-ticks/
|
|
* Set extremes off ticks
|
|
* @sample stock/members/axis-setextremes/
|
|
* Set extremes in Highstock
|
|
* @sample maps/members/axis-setextremes/
|
|
* Set extremes in Highmaps
|
|
*
|
|
* @function Highcharts.Axis#setExtremes
|
|
*
|
|
* @param {number} [newMin]
|
|
* The new minimum value.
|
|
*
|
|
* @param {number} [newMax]
|
|
* The new maximum value.
|
|
*
|
|
* @param {boolean} [redraw=true]
|
|
* Whether to redraw the chart or wait for an explicit call to
|
|
* {@link Highcharts.Chart#redraw}
|
|
*
|
|
* @param {boolean|Highcharts.AnimationOptionsObject} [animation=true]
|
|
* Enable or modify animations.
|
|
*
|
|
* @param {*} [eventArguments]
|
|
* Arguments to be accessed in event handler.
|
|
*
|
|
* @fires Highcharts.Axis#event:setExtremes
|
|
*/
|
|
Axis.prototype.setExtremes = function (newMin, newMax, redraw, animation, eventArguments) {
|
|
var axis = this, chart = axis.chart;
|
|
redraw = pick(redraw, true); // defaults to true
|
|
axis.series.forEach(function (serie) {
|
|
delete serie.kdTree;
|
|
});
|
|
// Extend the arguments with min and max
|
|
eventArguments = extend(eventArguments, {
|
|
min: newMin,
|
|
max: newMax
|
|
});
|
|
// Fire the event
|
|
fireEvent(axis, 'setExtremes', eventArguments, function () {
|
|
axis.userMin = newMin;
|
|
axis.userMax = newMax;
|
|
axis.eventArgs = eventArguments;
|
|
if (redraw) {
|
|
chart.redraw(animation);
|
|
}
|
|
});
|
|
};
|
|
/**
|
|
* Overridable method for zooming chart. Pulled out in a separate method to
|
|
* allow overriding in stock charts.
|
|
* @private
|
|
* @function Highcharts.Axis#zoom
|
|
*
|
|
* @param {number} newMin
|
|
* TO-DO: parameter description
|
|
*
|
|
* @param {number} newMax
|
|
* TO-DO: parameter description
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
Axis.prototype.zoom = function (newMin, newMax) {
|
|
var axis = this, dataMin = this.dataMin, dataMax = this.dataMax, options = this.options, min = Math.min(dataMin, pick(options.min, dataMin)), max = Math.max(dataMax, pick(options.max, dataMax)), evt = {
|
|
newMin: newMin,
|
|
newMax: newMax
|
|
};
|
|
fireEvent(this, 'zoom', evt, function (e) {
|
|
// Use e.newMin and e.newMax - event handlers may have altered them
|
|
var newMin = e.newMin, newMax = e.newMax;
|
|
if (newMin !== axis.min || newMax !== axis.max) { // #5790
|
|
// Prevent pinch zooming out of range. Check for defined is for
|
|
// #1946. #1734.
|
|
if (!axis.allowZoomOutside) {
|
|
// #6014, sometimes newMax will be smaller than min (or
|
|
// newMin will be larger than max).
|
|
if (defined(dataMin)) {
|
|
if (newMin < min) {
|
|
newMin = min;
|
|
}
|
|
if (newMin > max) {
|
|
newMin = max;
|
|
}
|
|
}
|
|
if (defined(dataMax)) {
|
|
if (newMax < min) {
|
|
newMax = min;
|
|
}
|
|
if (newMax > max) {
|
|
newMax = max;
|
|
}
|
|
}
|
|
}
|
|
// In full view, displaying the reset zoom button is not
|
|
// required
|
|
axis.displayBtn = (typeof newMin !== 'undefined' ||
|
|
typeof newMax !== 'undefined');
|
|
// Do it
|
|
axis.setExtremes(newMin, newMax, false, void 0, { trigger: 'zoom' });
|
|
}
|
|
e.zoomed = true;
|
|
});
|
|
return evt.zoomed;
|
|
};
|
|
/**
|
|
* Update the axis metrics.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#setAxisSize
|
|
*/
|
|
Axis.prototype.setAxisSize = function () {
|
|
var chart = this.chart, options = this.options,
|
|
// [top, right, bottom, left]
|
|
offsets = options.offsets || [0, 0, 0, 0], horiz = this.horiz,
|
|
// Check for percentage based input values. Rounding fixes problems
|
|
// with column overflow and plot line filtering (#4898, #4899)
|
|
width = this.width = Math.round(relativeLength(pick(options.width, chart.plotWidth - offsets[3] + offsets[1]), chart.plotWidth)), height = this.height = Math.round(relativeLength(pick(options.height, chart.plotHeight - offsets[0] + offsets[2]), chart.plotHeight)), top = this.top = Math.round(relativeLength(pick(options.top, chart.plotTop + offsets[0]), chart.plotHeight, chart.plotTop)), left = this.left = Math.round(relativeLength(pick(options.left, chart.plotLeft + offsets[3]), chart.plotWidth, chart.plotLeft));
|
|
// Expose basic values to use in Series object and navigator
|
|
this.bottom = chart.chartHeight - height - top;
|
|
this.right = chart.chartWidth - width - left;
|
|
// Direction agnostic properties
|
|
this.len = Math.max(horiz ? width : height, 0); // Math.max fixes #905
|
|
this.pos = horiz ? left : top; // distance from SVG origin
|
|
};
|
|
/**
|
|
* Get the current extremes for the axis.
|
|
*
|
|
* @sample highcharts/members/axis-getextremes/
|
|
* Report extremes by click on a button
|
|
* @sample maps/members/axis-getextremes/
|
|
* Get extremes in Highmaps
|
|
*
|
|
* @function Highcharts.Axis#getExtremes
|
|
*
|
|
* @return {Highcharts.ExtremesObject}
|
|
* An object containing extremes information.
|
|
*/
|
|
Axis.prototype.getExtremes = function () {
|
|
var axis = this;
|
|
var log = axis.logarithmic;
|
|
return {
|
|
min: log ?
|
|
correctFloat(log.lin2log(axis.min)) :
|
|
axis.min,
|
|
max: log ?
|
|
correctFloat(log.lin2log(axis.max)) :
|
|
axis.max,
|
|
dataMin: axis.dataMin,
|
|
dataMax: axis.dataMax,
|
|
userMin: axis.userMin,
|
|
userMax: axis.userMax
|
|
};
|
|
};
|
|
/**
|
|
* Get the zero plane either based on zero or on the min or max value.
|
|
* Used in bar and area plots.
|
|
*
|
|
* @function Highcharts.Axis#getThreshold
|
|
*
|
|
* @param {number} threshold
|
|
* The threshold in axis values.
|
|
*
|
|
* @return {number|undefined}
|
|
* The translated threshold position in terms of pixels, and corrected to
|
|
* stay within the axis bounds.
|
|
*/
|
|
Axis.prototype.getThreshold = function (threshold) {
|
|
var axis = this, log = axis.logarithmic, realMin = log ? log.lin2log(axis.min) : axis.min, realMax = log ? log.lin2log(axis.max) : axis.max;
|
|
if (threshold === null || threshold === -Infinity) {
|
|
threshold = realMin;
|
|
}
|
|
else if (threshold === Infinity) {
|
|
threshold = realMax;
|
|
}
|
|
else if (realMin > threshold) {
|
|
threshold = realMin;
|
|
}
|
|
else if (realMax < threshold) {
|
|
threshold = realMax;
|
|
}
|
|
return axis.translate(threshold, 0, 1, 0, 1);
|
|
};
|
|
/**
|
|
* Compute auto alignment for the axis label based on which side the axis is
|
|
* on and the given rotation for the label.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#autoLabelAlign
|
|
*
|
|
* @param {number} rotation
|
|
* The rotation in degrees as set by either the `rotation` or `autoRotation`
|
|
* options.
|
|
*
|
|
* @return {Highcharts.AlignValue}
|
|
* Can be `"center"`, `"left"` or `"right"`.
|
|
*/
|
|
Axis.prototype.autoLabelAlign = function (rotation) {
|
|
var angle = (pick(rotation, 0) - (this.side * 90) + 720) % 360, evt = { align: 'center' };
|
|
fireEvent(this, 'autoLabelAlign', evt, function (e) {
|
|
if (angle > 15 && angle < 165) {
|
|
e.align = 'right';
|
|
}
|
|
else if (angle > 195 && angle < 345) {
|
|
e.align = 'left';
|
|
}
|
|
});
|
|
return evt.align;
|
|
};
|
|
/**
|
|
* Get the tick length and width for the axis based on axis options.
|
|
* @private
|
|
* @function Highcharts.Axis#tickSize
|
|
*
|
|
* @param {string} [prefix]
|
|
* 'tick' or 'minorTick'
|
|
*
|
|
* @return {Array<number,number>|undefined}
|
|
* An array of tickLength and tickWidth
|
|
*/
|
|
Axis.prototype.tickSize = function (prefix) {
|
|
var options = this.options, tickLength = options[prefix === 'tick' ? 'tickLength' : 'minorTickLength'], tickWidth = pick(options[prefix === 'tick' ? 'tickWidth' : 'minorTickWidth'],
|
|
// Default to 1 on linear and datetime X axes
|
|
prefix === 'tick' && this.isXAxis && !this.categories ? 1 : 0), e, tickSize;
|
|
if (tickWidth && tickLength) {
|
|
// Negate the length
|
|
if (options[prefix + 'Position'] === 'inside') {
|
|
tickLength = -tickLength;
|
|
}
|
|
tickSize = [tickLength, tickWidth];
|
|
}
|
|
e = { tickSize: tickSize };
|
|
fireEvent(this, 'afterTickSize', e);
|
|
return e.tickSize;
|
|
};
|
|
/**
|
|
* Return the size of the labels.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#labelMetrics
|
|
*
|
|
* @return {Highcharts.FontMetricsObject}
|
|
*/
|
|
Axis.prototype.labelMetrics = function () {
|
|
var index = this.tickPositions && this.tickPositions[0] || 0;
|
|
return this.chart.renderer.fontMetrics(this.options.labels.style &&
|
|
this.options.labels.style.fontSize, this.ticks[index] && this.ticks[index].label);
|
|
};
|
|
/**
|
|
* Prevent the ticks from getting so close we can't draw the labels. On a
|
|
* horizontal axis, this is handled by rotating the labels, removing ticks
|
|
* and adding ellipsis. On a vertical axis remove ticks and add ellipsis.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#unsquish
|
|
*
|
|
* @return {number}
|
|
*/
|
|
Axis.prototype.unsquish = function () {
|
|
var labelOptions = this.options.labels, horiz = this.horiz, tickInterval = this.tickInterval, newTickInterval = tickInterval, slotSize = this.len / (((this.categories ? 1 : 0) +
|
|
this.max -
|
|
this.min) /
|
|
tickInterval), rotation, rotationOption = labelOptions.rotation, labelMetrics = this.labelMetrics(), step, bestScore = Number.MAX_VALUE, autoRotation, range = this.max - this.min,
|
|
// Return the multiple of tickInterval that is needed to avoid
|
|
// collision
|
|
getStep = function (spaceNeeded) {
|
|
var step = spaceNeeded / (slotSize || 1);
|
|
step = step > 1 ? Math.ceil(step) : 1;
|
|
// Guard for very small or negative angles (#9835)
|
|
if (step * tickInterval > range &&
|
|
spaceNeeded !== Infinity &&
|
|
slotSize !== Infinity &&
|
|
range) {
|
|
step = Math.ceil(range / tickInterval);
|
|
}
|
|
return correctFloat(step * tickInterval);
|
|
};
|
|
if (horiz) {
|
|
autoRotation = !labelOptions.staggerLines &&
|
|
!labelOptions.step &&
|
|
( // #3971
|
|
defined(rotationOption) ?
|
|
[rotationOption] :
|
|
slotSize < pick(labelOptions.autoRotationLimit, 80) && labelOptions.autoRotation);
|
|
if (autoRotation) {
|
|
// Loop over the given autoRotation options, and determine
|
|
// which gives the best score. The best score is that with
|
|
// the lowest number of steps and a rotation closest
|
|
// to horizontal.
|
|
autoRotation.forEach(function (rot) {
|
|
var score;
|
|
if (rot === rotationOption ||
|
|
(rot && rot >= -90 && rot <= 90)) { // #3891
|
|
step = getStep(Math.abs(labelMetrics.h / Math.sin(deg2rad * rot)));
|
|
score = step + Math.abs(rot / 360);
|
|
if (score < bestScore) {
|
|
bestScore = score;
|
|
rotation = rot;
|
|
newTickInterval = step;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
else if (!labelOptions.step) { // #4411
|
|
newTickInterval = getStep(labelMetrics.h);
|
|
}
|
|
this.autoRotation = autoRotation;
|
|
this.labelRotation = pick(rotation, rotationOption);
|
|
return newTickInterval;
|
|
};
|
|
/**
|
|
* Get the general slot width for labels/categories on this axis. This may
|
|
* change between the pre-render (from Axis.getOffset) and the final tick
|
|
* rendering and placement.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#getSlotWidth
|
|
*
|
|
* @param {Highcharts.Tick} [tick] Optionally, calculate the slot width
|
|
* basing on tick label. It is used in highcharts-3d module, where the slots
|
|
* has different widths depending on perspective angles.
|
|
*
|
|
* @return {number}
|
|
* The pixel width allocated to each axis label.
|
|
*/
|
|
Axis.prototype.getSlotWidth = function (tick) {
|
|
var _a;
|
|
// #5086, #1580, #1931
|
|
var chart = this.chart, horiz = this.horiz, labelOptions = this.options.labels, slotCount = Math.max(this.tickPositions.length - (this.categories ? 0 : 1), 1), marginLeft = chart.margin[3];
|
|
// Used by grid axis
|
|
if (tick && isNumber(tick.slotWidth)) { // #13221, can be 0
|
|
return tick.slotWidth;
|
|
}
|
|
if (horiz &&
|
|
labelOptions &&
|
|
(labelOptions.step || 0) < 2) {
|
|
if (labelOptions.rotation) { // #4415
|
|
return 0;
|
|
}
|
|
return ((this.staggerLines || 1) * this.len) / slotCount;
|
|
}
|
|
if (!horiz) {
|
|
// #7028
|
|
var cssWidth = (_a = labelOptions === null || labelOptions === void 0 ? void 0 : labelOptions.style) === null || _a === void 0 ? void 0 : _a.width;
|
|
if (cssWidth !== void 0) {
|
|
return parseInt(cssWidth, 10);
|
|
}
|
|
if (marginLeft) {
|
|
return marginLeft - chart.spacing[3];
|
|
}
|
|
}
|
|
// Last resort, a fraction of the available size
|
|
return chart.chartWidth * 0.33;
|
|
};
|
|
/**
|
|
* Render the axis labels and determine whether ellipsis or rotation need to
|
|
* be applied.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#renderUnsquish
|
|
*/
|
|
Axis.prototype.renderUnsquish = function () {
|
|
var chart = this.chart, renderer = chart.renderer, tickPositions = this.tickPositions, ticks = this.ticks, labelOptions = this.options.labels, labelStyleOptions = (labelOptions && labelOptions.style || {}), horiz = this.horiz, slotWidth = this.getSlotWidth(), innerWidth = Math.max(1, Math.round(slotWidth - 2 * (labelOptions.padding || 5))), attr = {}, labelMetrics = this.labelMetrics(), textOverflowOption = (labelOptions.style &&
|
|
labelOptions.style.textOverflow), commonWidth, commonTextOverflow, maxLabelLength = 0, label, i, pos;
|
|
// Set rotation option unless it is "auto", like in gauges
|
|
if (!isString(labelOptions.rotation)) {
|
|
// #4443:
|
|
attr.rotation = labelOptions.rotation || 0;
|
|
}
|
|
// Get the longest label length
|
|
tickPositions.forEach(function (tick) {
|
|
tick = ticks[tick];
|
|
// Replace label - sorting animation
|
|
if (tick.movedLabel) {
|
|
tick.replaceMovedLabel();
|
|
}
|
|
if (tick &&
|
|
tick.label &&
|
|
tick.label.textPxLength > maxLabelLength) {
|
|
maxLabelLength = tick.label.textPxLength;
|
|
}
|
|
});
|
|
this.maxLabelLength = maxLabelLength;
|
|
// Handle auto rotation on horizontal axis
|
|
if (this.autoRotation) {
|
|
// Apply rotation only if the label is too wide for the slot, and
|
|
// the label is wider than its height.
|
|
if (maxLabelLength > innerWidth &&
|
|
maxLabelLength > labelMetrics.h) {
|
|
attr.rotation = this.labelRotation;
|
|
}
|
|
else {
|
|
this.labelRotation = 0;
|
|
}
|
|
// Handle word-wrap or ellipsis on vertical axis
|
|
}
|
|
else if (slotWidth) {
|
|
// For word-wrap or ellipsis
|
|
commonWidth = innerWidth;
|
|
if (!textOverflowOption) {
|
|
commonTextOverflow = 'clip';
|
|
// On vertical axis, only allow word wrap if there is room
|
|
// for more lines.
|
|
i = tickPositions.length;
|
|
while (!horiz && i--) {
|
|
pos = tickPositions[i];
|
|
label = ticks[pos].label;
|
|
if (label) {
|
|
// Reset ellipsis in order to get the correct
|
|
// bounding box (#4070)
|
|
if (label.styles &&
|
|
label.styles.textOverflow === 'ellipsis') {
|
|
label.css({ textOverflow: 'clip' });
|
|
// Set the correct width in order to read
|
|
// the bounding box height (#4678, #5034)
|
|
}
|
|
else if (label.textPxLength > slotWidth) {
|
|
label.css({ width: slotWidth + 'px' });
|
|
}
|
|
if (label.getBBox().height > (this.len / tickPositions.length -
|
|
(labelMetrics.h - labelMetrics.f))) {
|
|
label.specificTextOverflow = 'ellipsis';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Add ellipsis if the label length is significantly longer than ideal
|
|
if (attr.rotation) {
|
|
commonWidth = (maxLabelLength > chart.chartHeight * 0.5 ?
|
|
chart.chartHeight * 0.33 :
|
|
maxLabelLength);
|
|
if (!textOverflowOption) {
|
|
commonTextOverflow = 'ellipsis';
|
|
}
|
|
}
|
|
// Set the explicit or automatic label alignment
|
|
this.labelAlign = labelOptions.align ||
|
|
this.autoLabelAlign(this.labelRotation);
|
|
if (this.labelAlign) {
|
|
attr.align = this.labelAlign;
|
|
}
|
|
// Apply general and specific CSS
|
|
tickPositions.forEach(function (pos) {
|
|
var tick = ticks[pos], label = tick && tick.label, widthOption = labelStyleOptions.width, css = {};
|
|
if (label) {
|
|
// This needs to go before the CSS in old IE (#4502)
|
|
label.attr(attr);
|
|
if (tick.shortenLabel) {
|
|
tick.shortenLabel();
|
|
}
|
|
else if (commonWidth &&
|
|
!widthOption &&
|
|
// Setting width in this case messes with the bounding box
|
|
// (#7975)
|
|
labelStyleOptions.whiteSpace !== 'nowrap' &&
|
|
(
|
|
// Speed optimizing, #7656
|
|
commonWidth < label.textPxLength ||
|
|
// Resetting CSS, #4928
|
|
label.element.tagName === 'SPAN')) {
|
|
css.width = commonWidth + 'px';
|
|
if (!textOverflowOption) {
|
|
css.textOverflow = (label.specificTextOverflow ||
|
|
commonTextOverflow);
|
|
}
|
|
label.css(css);
|
|
// Reset previously shortened label (#8210)
|
|
}
|
|
else if (label.styles &&
|
|
label.styles.width &&
|
|
!css.width &&
|
|
!widthOption) {
|
|
label.css({ width: null });
|
|
}
|
|
delete label.specificTextOverflow;
|
|
tick.rotation = attr.rotation;
|
|
}
|
|
}, this);
|
|
// Note: Why is this not part of getLabelPosition?
|
|
this.tickRotCorr = renderer.rotCorr(labelMetrics.b, this.labelRotation || 0, this.side !== 0);
|
|
};
|
|
/**
|
|
* Return true if the axis has associated data.
|
|
*
|
|
* @function Highcharts.Axis#hasData
|
|
*
|
|
* @return {boolean}
|
|
* True if the axis has associated visible series and those series have
|
|
* either valid data points or explicit `min` and `max` settings.
|
|
*/
|
|
Axis.prototype.hasData = function () {
|
|
return this.series.some(function (s) {
|
|
return s.hasData();
|
|
}) ||
|
|
(this.options.showEmpty &&
|
|
defined(this.min) &&
|
|
defined(this.max));
|
|
};
|
|
/**
|
|
* Adds the title defined in axis.options.title.
|
|
*
|
|
* @function Highcharts.Axis#addTitle
|
|
*
|
|
* @param {boolean} [display]
|
|
* Whether or not to display the title.
|
|
*/
|
|
Axis.prototype.addTitle = function (display) {
|
|
var axis = this, renderer = axis.chart.renderer, horiz = axis.horiz, opposite = axis.opposite, options = axis.options, axisTitleOptions = options.title, textAlign, styledMode = axis.chart.styledMode;
|
|
if (!axis.axisTitle) {
|
|
textAlign = axisTitleOptions.textAlign;
|
|
if (!textAlign) {
|
|
textAlign = (horiz ? {
|
|
low: 'left',
|
|
middle: 'center',
|
|
high: 'right'
|
|
} : {
|
|
low: opposite ? 'right' : 'left',
|
|
middle: 'center',
|
|
high: opposite ? 'left' : 'right'
|
|
})[axisTitleOptions.align];
|
|
}
|
|
axis.axisTitle = renderer
|
|
.text(axisTitleOptions.text, 0, 0, axisTitleOptions.useHTML)
|
|
.attr({
|
|
zIndex: 7,
|
|
rotation: axisTitleOptions.rotation || 0,
|
|
align: textAlign
|
|
})
|
|
.addClass('highcharts-axis-title');
|
|
// #7814, don't mutate style option
|
|
if (!styledMode) {
|
|
axis.axisTitle.css(merge(axisTitleOptions.style));
|
|
}
|
|
axis.axisTitle.add(axis.axisGroup);
|
|
axis.axisTitle.isNew = true;
|
|
}
|
|
// Max width defaults to the length of the axis
|
|
if (!styledMode &&
|
|
!axisTitleOptions.style.width &&
|
|
!axis.isRadial) {
|
|
axis.axisTitle.css({
|
|
width: axis.len + 'px'
|
|
});
|
|
}
|
|
// hide or show the title depending on whether showEmpty is set
|
|
axis.axisTitle[display ? 'show' : 'hide'](display);
|
|
};
|
|
/**
|
|
* Generates a tick for initial positioning.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#generateTick
|
|
*
|
|
* @param {number} pos
|
|
* The tick position in axis values.
|
|
*
|
|
* @param {number} [i]
|
|
* The index of the tick in {@link Axis.tickPositions}.
|
|
*/
|
|
Axis.prototype.generateTick = function (pos) {
|
|
var axis = this;
|
|
var ticks = axis.ticks;
|
|
if (!ticks[pos]) {
|
|
ticks[pos] = new Tick(axis, pos);
|
|
}
|
|
else {
|
|
ticks[pos].addLabel(); // update labels depending on tick interval
|
|
}
|
|
};
|
|
/**
|
|
* Render the tick labels to a preliminary position to get their sizes
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#getOffset
|
|
*
|
|
* @fires Highcharts.Axis#event:afterGetOffset
|
|
*/
|
|
Axis.prototype.getOffset = function () {
|
|
var axis = this, chart = axis.chart, renderer = chart.renderer, options = axis.options, tickPositions = axis.tickPositions, ticks = axis.ticks, horiz = axis.horiz, side = axis.side, invertedSide = chart.inverted &&
|
|
!axis.isZAxis ? [1, 0, 3, 2][side] : side, hasData, showAxis, titleOffset = 0, titleOffsetOption, titleMargin = 0, axisTitleOptions = options.title, labelOptions = options.labels, labelOffset = 0, // reset
|
|
labelOffsetPadded, axisOffset = chart.axisOffset, clipOffset = chart.clipOffset, clip, directionFactor = [-1, 1, 1, -1][side], className = options.className, axisParent = axis.axisParent, // Used in color axis
|
|
lineHeightCorrection;
|
|
// For reuse in Axis.render
|
|
hasData = axis.hasData();
|
|
axis.showAxis = showAxis = hasData || pick(options.showEmpty, true);
|
|
// Set/reset staggerLines
|
|
axis.staggerLines = axis.horiz && labelOptions.staggerLines;
|
|
// Create the axisGroup and gridGroup elements on first iteration
|
|
if (!axis.axisGroup) {
|
|
axis.gridGroup = renderer.g('grid')
|
|
.attr({ zIndex: options.gridZIndex || 1 })
|
|
.addClass('highcharts-' + this.coll.toLowerCase() + '-grid ' +
|
|
(className || ''))
|
|
.add(axisParent);
|
|
axis.axisGroup = renderer.g('axis')
|
|
.attr({ zIndex: options.zIndex || 2 })
|
|
.addClass('highcharts-' + this.coll.toLowerCase() + ' ' +
|
|
(className || ''))
|
|
.add(axisParent);
|
|
axis.labelGroup = renderer.g('axis-labels')
|
|
.attr({ zIndex: labelOptions.zIndex || 7 })
|
|
.addClass('highcharts-' + axis.coll.toLowerCase() + '-labels ' +
|
|
(className || ''))
|
|
.add(axisParent);
|
|
}
|
|
if (hasData || axis.isLinked) {
|
|
// Generate ticks
|
|
tickPositions.forEach(function (pos, i) {
|
|
// i is not used here, but may be used in overrides
|
|
axis.generateTick(pos, i);
|
|
});
|
|
axis.renderUnsquish();
|
|
// Left side must be align: right and right side must
|
|
// have align: left for labels
|
|
axis.reserveSpaceDefault = (side === 0 ||
|
|
side === 2 ||
|
|
{ 1: 'left', 3: 'right' }[side] === axis.labelAlign);
|
|
if (pick(labelOptions.reserveSpace, axis.labelAlign === 'center' ? true : null, axis.reserveSpaceDefault)) {
|
|
tickPositions.forEach(function (pos) {
|
|
// get the highest offset
|
|
labelOffset = Math.max(ticks[pos].getLabelSize(), labelOffset);
|
|
});
|
|
}
|
|
if (axis.staggerLines) {
|
|
labelOffset *= axis.staggerLines;
|
|
}
|
|
axis.labelOffset = labelOffset * (axis.opposite ? -1 : 1);
|
|
}
|
|
else { // doesn't have data
|
|
objectEach(ticks, function (tick, n) {
|
|
tick.destroy();
|
|
delete ticks[n];
|
|
});
|
|
}
|
|
if (axisTitleOptions &&
|
|
axisTitleOptions.text &&
|
|
axisTitleOptions.enabled !== false) {
|
|
axis.addTitle(showAxis);
|
|
if (showAxis && axisTitleOptions.reserveSpace !== false) {
|
|
axis.titleOffset = titleOffset =
|
|
axis.axisTitle.getBBox()[horiz ? 'height' : 'width'];
|
|
titleOffsetOption = axisTitleOptions.offset;
|
|
titleMargin = defined(titleOffsetOption) ?
|
|
0 :
|
|
pick(axisTitleOptions.margin, horiz ? 5 : 10);
|
|
}
|
|
}
|
|
// Render the axis line
|
|
axis.renderLine();
|
|
// handle automatic or user set offset
|
|
axis.offset = directionFactor * pick(options.offset, axisOffset[side] ? axisOffset[side] + (options.margin || 0) : 0);
|
|
axis.tickRotCorr = axis.tickRotCorr || { x: 0, y: 0 }; // polar
|
|
if (side === 0) {
|
|
lineHeightCorrection = -axis.labelMetrics().h;
|
|
}
|
|
else if (side === 2) {
|
|
lineHeightCorrection = axis.tickRotCorr.y;
|
|
}
|
|
else {
|
|
lineHeightCorrection = 0;
|
|
}
|
|
// Find the padded label offset
|
|
labelOffsetPadded = Math.abs(labelOffset) + titleMargin;
|
|
if (labelOffset) {
|
|
labelOffsetPadded -= lineHeightCorrection;
|
|
labelOffsetPadded += directionFactor * (horiz ?
|
|
pick(labelOptions.y, axis.tickRotCorr.y + directionFactor * 8) :
|
|
labelOptions.x);
|
|
}
|
|
axis.axisTitleMargin = pick(titleOffsetOption, labelOffsetPadded);
|
|
if (axis.getMaxLabelDimensions) {
|
|
axis.maxLabelDimensions = axis.getMaxLabelDimensions(ticks, tickPositions);
|
|
}
|
|
// Due to GridAxis.tickSize, tickSize should be calculated after ticks
|
|
// has rendered.
|
|
var tickSize = this.tickSize('tick');
|
|
axisOffset[side] = Math.max(axisOffset[side], axis.axisTitleMargin + titleOffset +
|
|
directionFactor * axis.offset, labelOffsetPadded, // #3027
|
|
tickPositions && tickPositions.length && tickSize ?
|
|
tickSize[0] + directionFactor * axis.offset :
|
|
0 // #4866
|
|
);
|
|
// Decide the clipping needed to keep the graph inside
|
|
// the plot area and axis lines
|
|
clip = options.offset ?
|
|
0 :
|
|
// #4308, #4371:
|
|
Math.floor(axis.axisLine.strokeWidth() / 2) * 2;
|
|
clipOffset[invertedSide] =
|
|
Math.max(clipOffset[invertedSide], clip);
|
|
fireEvent(this, 'afterGetOffset');
|
|
};
|
|
/**
|
|
* Internal function to get the path for the axis line. Extended for polar
|
|
* charts.
|
|
*
|
|
* @function Highcharts.Axis#getLinePath
|
|
*
|
|
* @param {number} lineWidth
|
|
* The line width in pixels.
|
|
*
|
|
* @return {Highcharts.SVGPathArray}
|
|
* The SVG path definition in array form.
|
|
*/
|
|
Axis.prototype.getLinePath = function (lineWidth) {
|
|
var chart = this.chart, opposite = this.opposite, offset = this.offset, horiz = this.horiz, lineLeft = this.left + (opposite ? this.width : 0) + offset, lineTop = chart.chartHeight - this.bottom -
|
|
(opposite ? this.height : 0) + offset;
|
|
if (opposite) {
|
|
lineWidth *= -1; // crispify the other way - #1480, #1687
|
|
}
|
|
return chart.renderer
|
|
.crispLine([
|
|
[
|
|
'M',
|
|
horiz ?
|
|
this.left :
|
|
lineLeft,
|
|
horiz ?
|
|
lineTop :
|
|
this.top
|
|
],
|
|
[
|
|
'L',
|
|
horiz ?
|
|
chart.chartWidth - this.right :
|
|
lineLeft,
|
|
horiz ?
|
|
lineTop :
|
|
chart.chartHeight - this.bottom
|
|
]
|
|
], lineWidth);
|
|
};
|
|
/**
|
|
* Render the axis line. Called internally when rendering and redrawing the
|
|
* axis.
|
|
*
|
|
* @function Highcharts.Axis#renderLine
|
|
*/
|
|
Axis.prototype.renderLine = function () {
|
|
if (!this.axisLine) {
|
|
this.axisLine = this.chart.renderer.path()
|
|
.addClass('highcharts-axis-line')
|
|
.add(this.axisGroup);
|
|
if (!this.chart.styledMode) {
|
|
this.axisLine.attr({
|
|
stroke: this.options.lineColor,
|
|
'stroke-width': this.options.lineWidth,
|
|
zIndex: 7
|
|
});
|
|
}
|
|
}
|
|
};
|
|
/**
|
|
* Position the axis title.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#getTitlePosition
|
|
*
|
|
* @return {Highcharts.PositionObject}
|
|
* X and Y positions for the title.
|
|
*/
|
|
Axis.prototype.getTitlePosition = function () {
|
|
// compute anchor points for each of the title align options
|
|
var horiz = this.horiz, axisLeft = this.left, axisTop = this.top, axisLength = this.len, axisTitleOptions = this.options.title, margin = horiz ? axisLeft : axisTop, opposite = this.opposite, offset = this.offset, xOption = axisTitleOptions.x || 0, yOption = axisTitleOptions.y || 0, axisTitle = this.axisTitle, fontMetrics = this.chart.renderer.fontMetrics(axisTitleOptions.style &&
|
|
axisTitleOptions.style.fontSize, axisTitle),
|
|
// The part of a multiline text that is below the baseline of the
|
|
// first line. Subtract 1 to preserve pixel-perfectness from the
|
|
// old behaviour (v5.0.12), where only one line was allowed.
|
|
textHeightOvershoot = Math.max(axisTitle.getBBox(null, 0).height - fontMetrics.h - 1, 0),
|
|
// the position in the length direction of the axis
|
|
alongAxis = {
|
|
low: margin + (horiz ? 0 : axisLength),
|
|
middle: margin + axisLength / 2,
|
|
high: margin + (horiz ? axisLength : 0)
|
|
}[axisTitleOptions.align],
|
|
// the position in the perpendicular direction of the axis
|
|
offAxis = (horiz ? axisTop + this.height : axisLeft) +
|
|
(horiz ? 1 : -1) * // horizontal axis reverses the margin
|
|
(opposite ? -1 : 1) * // so does opposite axes
|
|
this.axisTitleMargin +
|
|
[
|
|
-textHeightOvershoot,
|
|
textHeightOvershoot,
|
|
fontMetrics.f,
|
|
-textHeightOvershoot // left
|
|
][this.side], titlePosition = {
|
|
x: horiz ?
|
|
alongAxis + xOption :
|
|
offAxis + (opposite ? this.width : 0) + offset + xOption,
|
|
y: horiz ?
|
|
offAxis + yOption - (opposite ? this.height : 0) + offset :
|
|
alongAxis + yOption
|
|
};
|
|
fireEvent(this, 'afterGetTitlePosition', { titlePosition: titlePosition });
|
|
return titlePosition;
|
|
};
|
|
/**
|
|
* Render a minor tick into the given position. If a minor tick already
|
|
* exists in this position, move it.
|
|
*
|
|
* @function Highcharts.Axis#renderMinorTick
|
|
*
|
|
* @param {number} pos
|
|
* The position in axis values.
|
|
*/
|
|
Axis.prototype.renderMinorTick = function (pos) {
|
|
var axis = this;
|
|
var slideInTicks = axis.chart.hasRendered && isNumber(axis.oldMin);
|
|
var minorTicks = axis.minorTicks;
|
|
if (!minorTicks[pos]) {
|
|
minorTicks[pos] = new Tick(axis, pos, 'minor');
|
|
}
|
|
// Render new ticks in old position
|
|
if (slideInTicks && minorTicks[pos].isNew) {
|
|
minorTicks[pos].render(null, true);
|
|
}
|
|
minorTicks[pos].render(null, false, 1);
|
|
};
|
|
/**
|
|
* Render a major tick into the given position. If a tick already exists
|
|
* in this position, move it.
|
|
*
|
|
* @function Highcharts.Axis#renderTick
|
|
*
|
|
* @param {number} pos
|
|
* The position in axis values.
|
|
*
|
|
* @param {number} i
|
|
* The tick index.
|
|
*/
|
|
Axis.prototype.renderTick = function (pos, i) {
|
|
var axis = this;
|
|
var isLinked = axis.isLinked;
|
|
var ticks = axis.ticks;
|
|
var slideInTicks = axis.chart.hasRendered && isNumber(axis.oldMin);
|
|
// Linked axes need an extra check to find out if
|
|
if (!isLinked ||
|
|
(pos >= axis.min && pos <= axis.max)) {
|
|
if (!ticks[pos]) {
|
|
ticks[pos] = new Tick(axis, pos);
|
|
}
|
|
// NOTE this seems like overkill. Could be handled in tick.render by
|
|
// setting old position in attr, then set new position in animate.
|
|
// render new ticks in old position
|
|
if (slideInTicks && ticks[pos].isNew) {
|
|
// Start with negative opacity so that it is visible from
|
|
// halfway into the animation
|
|
ticks[pos].render(i, true, -1);
|
|
}
|
|
ticks[pos].render(i);
|
|
}
|
|
};
|
|
/**
|
|
* Render the axis.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#render
|
|
*
|
|
* @fires Highcharts.Axis#event:afterRender
|
|
*/
|
|
Axis.prototype.render = function () {
|
|
var axis = this, chart = axis.chart, log = axis.logarithmic, renderer = chart.renderer, options = axis.options, isLinked = axis.isLinked, tickPositions = axis.tickPositions, axisTitle = axis.axisTitle, ticks = axis.ticks, minorTicks = axis.minorTicks, alternateBands = axis.alternateBands, stackLabelOptions = options.stackLabels, alternateGridColor = options.alternateGridColor, tickmarkOffset = axis.tickmarkOffset, axisLine = axis.axisLine, showAxis = axis.showAxis, animation = animObject(renderer.globalAnimation), from, to;
|
|
// Reset
|
|
axis.labelEdge.length = 0;
|
|
axis.overlap = false;
|
|
// Mark all elements inActive before we go over and mark the active ones
|
|
[ticks, minorTicks, alternateBands].forEach(function (coll) {
|
|
objectEach(coll, function (tick) {
|
|
tick.isActive = false;
|
|
});
|
|
});
|
|
// If the series has data draw the ticks. Else only the line and title
|
|
if (axis.hasData() || isLinked) {
|
|
// minor ticks
|
|
if (axis.minorTickInterval && !axis.categories) {
|
|
axis.getMinorTickPositions().forEach(function (pos) {
|
|
axis.renderMinorTick(pos);
|
|
});
|
|
}
|
|
// Major ticks. Pull out the first item and render it last so that
|
|
// we can get the position of the neighbour label. #808.
|
|
if (tickPositions.length) { // #1300
|
|
tickPositions.forEach(function (pos, i) {
|
|
axis.renderTick(pos, i);
|
|
});
|
|
// In a categorized axis, the tick marks are displayed
|
|
// between labels. So we need to add a tick mark and
|
|
// grid line at the left edge of the X axis.
|
|
if (tickmarkOffset && (axis.min === 0 || axis.single)) {
|
|
if (!ticks[-1]) {
|
|
ticks[-1] = new Tick(axis, -1, null, true);
|
|
}
|
|
ticks[-1].render(-1);
|
|
}
|
|
}
|
|
// alternate grid color
|
|
if (alternateGridColor) {
|
|
tickPositions.forEach(function (pos, i) {
|
|
to = typeof tickPositions[i + 1] !== 'undefined' ?
|
|
tickPositions[i + 1] + tickmarkOffset :
|
|
axis.max - tickmarkOffset;
|
|
if (i % 2 === 0 &&
|
|
pos < axis.max &&
|
|
to <= axis.max + (chart.polar ?
|
|
-tickmarkOffset :
|
|
tickmarkOffset)) { // #2248, #4660
|
|
if (!alternateBands[pos]) {
|
|
// Should be imported from PlotLineOrBand.js, but
|
|
// the dependency cycle with axis is a problem
|
|
alternateBands[pos] = new H.PlotLineOrBand(axis);
|
|
}
|
|
from = pos + tickmarkOffset; // #949
|
|
alternateBands[pos].options = {
|
|
from: log ? log.lin2log(from) : from,
|
|
to: log ? log.lin2log(to) : to,
|
|
color: alternateGridColor
|
|
};
|
|
alternateBands[pos].render();
|
|
alternateBands[pos].isActive = true;
|
|
}
|
|
});
|
|
}
|
|
// custom plot lines and bands
|
|
if (!axis._addedPlotLB) { // only first time
|
|
(options.plotLines || [])
|
|
.concat(options.plotBands || [])
|
|
.forEach(function (plotLineOptions) {
|
|
axis.addPlotBandOrLine(plotLineOptions);
|
|
});
|
|
axis._addedPlotLB = true;
|
|
}
|
|
} // end if hasData
|
|
// Remove inactive ticks
|
|
[ticks, minorTicks, alternateBands].forEach(function (coll) {
|
|
var i, forDestruction = [], delay = animation.duration, destroyInactiveItems = function () {
|
|
i = forDestruction.length;
|
|
while (i--) {
|
|
// When resizing rapidly, the same items
|
|
// may be destroyed in different timeouts,
|
|
// or the may be reactivated
|
|
if (coll[forDestruction[i]] &&
|
|
!coll[forDestruction[i]].isActive) {
|
|
coll[forDestruction[i]].destroy();
|
|
delete coll[forDestruction[i]];
|
|
}
|
|
}
|
|
};
|
|
objectEach(coll, function (tick, pos) {
|
|
if (!tick.isActive) {
|
|
// Render to zero opacity
|
|
tick.render(pos, false, 0);
|
|
tick.isActive = false;
|
|
forDestruction.push(pos);
|
|
}
|
|
});
|
|
// When the objects are finished fading out, destroy them
|
|
syncTimeout(destroyInactiveItems, coll === alternateBands ||
|
|
!chart.hasRendered ||
|
|
!delay ?
|
|
0 :
|
|
delay);
|
|
});
|
|
// Set the axis line path
|
|
if (axisLine) {
|
|
axisLine[axisLine.isPlaced ? 'animate' : 'attr']({
|
|
d: this.getLinePath(axisLine.strokeWidth())
|
|
});
|
|
axisLine.isPlaced = true;
|
|
// Show or hide the line depending on options.showEmpty
|
|
axisLine[showAxis ? 'show' : 'hide'](showAxis);
|
|
}
|
|
if (axisTitle && showAxis) {
|
|
var titleXy = axis.getTitlePosition();
|
|
if (isNumber(titleXy.y)) {
|
|
axisTitle[axisTitle.isNew ? 'attr' : 'animate'](titleXy);
|
|
axisTitle.isNew = false;
|
|
}
|
|
else {
|
|
axisTitle.attr('y', -9999);
|
|
axisTitle.isNew = true;
|
|
}
|
|
}
|
|
// Stacked totals:
|
|
if (stackLabelOptions && stackLabelOptions.enabled && axis.stacking) {
|
|
axis.stacking.renderStackTotals();
|
|
}
|
|
// End stacked totals
|
|
axis.isDirty = false;
|
|
fireEvent(this, 'afterRender');
|
|
};
|
|
/**
|
|
* Redraw the axis to reflect changes in the data or axis extremes. Called
|
|
* internally from Highcharts.Chart#redraw.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#redraw
|
|
*/
|
|
Axis.prototype.redraw = function () {
|
|
if (this.visible) {
|
|
// render the axis
|
|
this.render();
|
|
// move plot lines and bands
|
|
this.plotLinesAndBands.forEach(function (plotLine) {
|
|
plotLine.render();
|
|
});
|
|
}
|
|
// mark associated series as dirty and ready for redraw
|
|
this.series.forEach(function (series) {
|
|
series.isDirty = true;
|
|
});
|
|
};
|
|
/**
|
|
* Returns an array of axis properties, that should be untouched during
|
|
* reinitialization.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#getKeepProps
|
|
*
|
|
* @return {Array<string>}
|
|
*/
|
|
Axis.prototype.getKeepProps = function () {
|
|
return (this.keepProps || Axis.keepProps);
|
|
};
|
|
/**
|
|
* Destroys an Axis instance. See {@link Axis#remove} for the API endpoint
|
|
* to fully remove the axis.
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#destroy
|
|
*
|
|
* @param {boolean} [keepEvents]
|
|
* Whether to preserve events, used internally in Axis.update.
|
|
*/
|
|
Axis.prototype.destroy = function (keepEvents) {
|
|
var axis = this, plotLinesAndBands = axis.plotLinesAndBands, plotGroup, i;
|
|
fireEvent(this, 'destroy', { keepEvents: keepEvents });
|
|
// Remove the events
|
|
if (!keepEvents) {
|
|
removeEvent(axis);
|
|
}
|
|
// Destroy collections
|
|
[axis.ticks, axis.minorTicks, axis.alternateBands].forEach(function (coll) {
|
|
destroyObjectProperties(coll);
|
|
});
|
|
if (plotLinesAndBands) {
|
|
i = plotLinesAndBands.length;
|
|
while (i--) { // #1975
|
|
plotLinesAndBands[i].destroy();
|
|
}
|
|
}
|
|
// Destroy elements
|
|
['axisLine', 'axisTitle', 'axisGroup',
|
|
'gridGroup', 'labelGroup', 'cross', 'scrollbar'].forEach(function (prop) {
|
|
if (axis[prop]) {
|
|
axis[prop] = axis[prop].destroy();
|
|
}
|
|
});
|
|
// Destroy each generated group for plotlines and plotbands
|
|
for (plotGroup in axis.plotLinesAndBandsGroups) { // eslint-disable-line guard-for-in
|
|
axis.plotLinesAndBandsGroups[plotGroup] =
|
|
axis.plotLinesAndBandsGroups[plotGroup].destroy();
|
|
}
|
|
// Delete all properties and fall back to the prototype.
|
|
objectEach(axis, function (val, key) {
|
|
if (axis.getKeepProps().indexOf(key) === -1) {
|
|
delete axis[key];
|
|
}
|
|
});
|
|
};
|
|
/**
|
|
* Internal function to draw a crosshair.
|
|
*
|
|
* @function Highcharts.Axis#drawCrosshair
|
|
*
|
|
* @param {Highcharts.PointerEventObject} [e]
|
|
* The event arguments from the modified pointer event, extended with
|
|
* `chartX` and `chartY`
|
|
*
|
|
* @param {Highcharts.Point} [point]
|
|
* The Point object if the crosshair snaps to points.
|
|
*
|
|
* @fires Highcharts.Axis#event:afterDrawCrosshair
|
|
* @fires Highcharts.Axis#event:drawCrosshair
|
|
*/
|
|
Axis.prototype.drawCrosshair = function (e, point) {
|
|
var path, options = this.crosshair, snap = pick(options.snap, true), pos, categorized, graphic = this.cross, crossOptions, chart = this.chart;
|
|
fireEvent(this, 'drawCrosshair', { e: e, point: point });
|
|
// Use last available event when updating non-snapped crosshairs without
|
|
// mouse interaction (#5287)
|
|
if (!e) {
|
|
e = this.cross && this.cross.e;
|
|
}
|
|
if (
|
|
// Disabled in options
|
|
!this.crosshair ||
|
|
// Snap
|
|
((defined(point) || !snap) === false)) {
|
|
this.hideCrosshair();
|
|
}
|
|
else {
|
|
// Get the path
|
|
if (!snap) {
|
|
pos = e &&
|
|
(this.horiz ?
|
|
e.chartX - this.pos :
|
|
this.len - e.chartY + this.pos);
|
|
}
|
|
else if (defined(point)) {
|
|
// #3834
|
|
pos = pick(this.coll !== 'colorAxis' ?
|
|
point.crosshairPos : // 3D axis extension
|
|
null, this.isXAxis ?
|
|
point.plotX :
|
|
this.len - point.plotY);
|
|
}
|
|
if (defined(pos)) {
|
|
crossOptions = {
|
|
// value, only used on radial
|
|
value: point && (this.isXAxis ?
|
|
point.x :
|
|
pick(point.stackY, point.y)),
|
|
translatedValue: pos
|
|
};
|
|
if (chart.polar) {
|
|
// Additional information required for crosshairs in
|
|
// polar chart
|
|
extend(crossOptions, {
|
|
isCrosshair: true,
|
|
chartX: e && e.chartX,
|
|
chartY: e && e.chartY,
|
|
point: point
|
|
});
|
|
}
|
|
path = this.getPlotLinePath(crossOptions) ||
|
|
null; // #3189
|
|
}
|
|
if (!defined(path)) {
|
|
this.hideCrosshair();
|
|
return;
|
|
}
|
|
categorized = this.categories && !this.isRadial;
|
|
// Draw the cross
|
|
if (!graphic) {
|
|
this.cross = graphic = chart.renderer
|
|
.path()
|
|
.addClass('highcharts-crosshair highcharts-crosshair-' +
|
|
(categorized ? 'category ' : 'thin ') +
|
|
options.className)
|
|
.attr({
|
|
zIndex: pick(options.zIndex, 2)
|
|
})
|
|
.add();
|
|
// Presentational attributes
|
|
if (!chart.styledMode) {
|
|
graphic.attr({
|
|
stroke: options.color ||
|
|
(categorized ?
|
|
Color
|
|
.parse('#ccd6eb')
|
|
.setOpacity(0.25)
|
|
.get() :
|
|
'#cccccc'),
|
|
'stroke-width': pick(options.width, 1)
|
|
}).css({
|
|
'pointer-events': 'none'
|
|
});
|
|
if (options.dashStyle) {
|
|
graphic.attr({
|
|
dashstyle: options.dashStyle
|
|
});
|
|
}
|
|
}
|
|
}
|
|
graphic.show().attr({
|
|
d: path
|
|
});
|
|
if (categorized && !options.width) {
|
|
graphic.attr({
|
|
'stroke-width': this.transA
|
|
});
|
|
}
|
|
this.cross.e = e;
|
|
}
|
|
fireEvent(this, 'afterDrawCrosshair', { e: e, point: point });
|
|
};
|
|
/**
|
|
* Hide the crosshair if visible.
|
|
*
|
|
* @function Highcharts.Axis#hideCrosshair
|
|
*/
|
|
Axis.prototype.hideCrosshair = function () {
|
|
if (this.cross) {
|
|
this.cross.hide();
|
|
}
|
|
fireEvent(this, 'afterHideCrosshair');
|
|
};
|
|
/**
|
|
* Check whether the chart has vertical panning ('y' or 'xy' type).
|
|
*
|
|
* @private
|
|
* @function Highcharts.Axis#hasVerticalPanning
|
|
* @return {boolean}
|
|
*
|
|
*/
|
|
Axis.prototype.hasVerticalPanning = function () {
|
|
var _a, _b;
|
|
return /y/.test(((_b = (_a = this.chart.options.chart) === null || _a === void 0 ? void 0 : _a.panning) === null || _b === void 0 ? void 0 : _b.type) || '');
|
|
};
|
|
/* *
|
|
*
|
|
* Static Properties
|
|
*
|
|
* */
|
|
/**
|
|
* The X axis or category axis. Normally this is the horizontal axis,
|
|
* though if the chart is inverted this is the vertical axis. In case of
|
|
* multiple axes, the xAxis node is an array of configuration objects.
|
|
*
|
|
* See the [Axis class](/class-reference/Highcharts.Axis) for programmatic
|
|
* access to the axis.
|
|
*
|
|
* @productdesc {highmaps}
|
|
* In Highmaps, the axis is hidden, but it is used behind the scenes to
|
|
* control features like zooming and panning. Zooming is in effect the same
|
|
* as setting the extremes of one of the exes.
|
|
*
|
|
* @type {*|Array<*>}
|
|
* @optionparent xAxis
|
|
*
|
|
* @private
|
|
*/
|
|
Axis.defaultOptions = {
|
|
/**
|
|
* When using multiple axis, the ticks of two or more opposite axes
|
|
* will automatically be aligned by adding ticks to the axis or axes
|
|
* with the least ticks, as if `tickAmount` were specified.
|
|
*
|
|
* This can be prevented by setting `alignTicks` to false. If the grid
|
|
* lines look messy, it's a good idea to hide them for the secondary
|
|
* axis by setting `gridLineWidth` to 0.
|
|
*
|
|
* If `startOnTick` or `endOnTick` in an Axis options are set to false,
|
|
* then the `alignTicks ` will be disabled for the Axis.
|
|
*
|
|
* Disabled for logarithmic axes.
|
|
*
|
|
* @type {boolean}
|
|
* @default true
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.alignTicks
|
|
*/
|
|
/**
|
|
* Whether to allow decimals in this axis' ticks. When counting
|
|
* integers, like persons or hits on a web page, decimals should
|
|
* be avoided in the labels.
|
|
*
|
|
* @see [minTickInterval](#xAxis.minTickInterval)
|
|
*
|
|
* @sample {highcharts|highstock} highcharts/yaxis/allowdecimals-true/
|
|
* True by default
|
|
* @sample {highcharts|highstock} highcharts/yaxis/allowdecimals-false/
|
|
* False
|
|
*
|
|
* @type {boolean}
|
|
* @default true
|
|
* @since 2.0
|
|
* @apioption xAxis.allowDecimals
|
|
*/
|
|
/**
|
|
* When using an alternate grid color, a band is painted across the
|
|
* plot area between every other grid line.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/alternategridcolor/
|
|
* Alternate grid color on the Y axis
|
|
* @sample {highstock} stock/xaxis/alternategridcolor/
|
|
* Alternate grid color on the Y axis
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @apioption xAxis.alternateGridColor
|
|
*/
|
|
/**
|
|
* An array defining breaks in the axis, the sections defined will be
|
|
* left out and all the points shifted closer to each other.
|
|
*
|
|
* @productdesc {highcharts}
|
|
* Requires that the broken-axis.js module is loaded.
|
|
*
|
|
* @sample {highcharts} highcharts/axisbreak/break-simple/
|
|
* Simple break
|
|
* @sample {highcharts|highstock} highcharts/axisbreak/break-visualized/
|
|
* Advanced with callback
|
|
* @sample {highstock} stock/demo/intraday-breaks/
|
|
* Break on nights and weekends
|
|
*
|
|
* @type {Array<*>}
|
|
* @since 4.1.0
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.breaks
|
|
*/
|
|
/**
|
|
* A number indicating how much space should be left between the start
|
|
* and the end of the break. The break size is given in axis units,
|
|
* so for instance on a `datetime` axis, a break size of 3600000 would
|
|
* indicate the equivalent of an hour.
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 4.1.0
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.breaks.breakSize
|
|
*/
|
|
/**
|
|
* The point where the break starts.
|
|
*
|
|
* @type {number}
|
|
* @since 4.1.0
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.breaks.from
|
|
*/
|
|
/**
|
|
* Defines an interval after which the break appears again. By default
|
|
* the breaks do not repeat.
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 4.1.0
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.breaks.repeat
|
|
*/
|
|
/**
|
|
* The point where the break ends.
|
|
*
|
|
* @type {number}
|
|
* @since 4.1.0
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.breaks.to
|
|
*/
|
|
/**
|
|
* If categories are present for the xAxis, names are used instead of
|
|
* numbers for that axis.
|
|
*
|
|
* Since Highcharts 3.0, categories can also
|
|
* be extracted by giving each point a [name](#series.data) and setting
|
|
* axis [type](#xAxis.type) to `category`. However, if you have multiple
|
|
* series, best practice remains defining the `categories` array.
|
|
*
|
|
* Example: `categories: ['Apples', 'Bananas', 'Oranges']`
|
|
*
|
|
* @sample {highcharts} highcharts/demo/line-labels/
|
|
* With
|
|
* @sample {highcharts} highcharts/xaxis/categories/
|
|
* Without
|
|
*
|
|
* @type {Array<string>}
|
|
* @product highcharts gantt
|
|
* @apioption xAxis.categories
|
|
*/
|
|
/**
|
|
* The highest allowed value for automatically computed axis extremes.
|
|
*
|
|
* @see [floor](#xAxis.floor)
|
|
*
|
|
* @sample {highcharts|highstock} highcharts/yaxis/floor-ceiling/
|
|
* Floor and ceiling
|
|
*
|
|
* @type {number}
|
|
* @since 4.0
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.ceiling
|
|
*/
|
|
/**
|
|
* A class name that opens for styling the axis by CSS, especially in
|
|
* Highcharts styled mode. The class name is applied to group elements
|
|
* for the grid, axis elements and labels.
|
|
*
|
|
* @sample {highcharts|highstock|highmaps} highcharts/css/axis/
|
|
* Multiple axes with separate styling
|
|
*
|
|
* @type {string}
|
|
* @since 5.0.0
|
|
* @apioption xAxis.className
|
|
*/
|
|
/**
|
|
* Configure a crosshair that follows either the mouse pointer or the
|
|
* hovered point.
|
|
*
|
|
* In styled mode, the crosshairs are styled in the
|
|
* `.highcharts-crosshair`, `.highcharts-crosshair-thin` or
|
|
* `.highcharts-xaxis-category` classes.
|
|
*
|
|
* @productdesc {highstock}
|
|
* In Highstock, by default, the crosshair is enabled on the X axis and
|
|
* disabled on the Y axis.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/crosshair-both/
|
|
* Crosshair on both axes
|
|
* @sample {highstock} stock/xaxis/crosshairs-xy/
|
|
* Crosshair on both axes
|
|
* @sample {highmaps} highcharts/xaxis/crosshair-both/
|
|
* Crosshair on both axes
|
|
*
|
|
* @declare Highcharts.AxisCrosshairOptions
|
|
* @type {boolean|*}
|
|
* @default false
|
|
* @since 4.1
|
|
* @apioption xAxis.crosshair
|
|
*/
|
|
/**
|
|
* A class name for the crosshair, especially as a hook for styling.
|
|
*
|
|
* @type {string}
|
|
* @since 5.0.0
|
|
* @apioption xAxis.crosshair.className
|
|
*/
|
|
/**
|
|
* The color of the crosshair. Defaults to `#cccccc` for numeric and
|
|
* datetime axes, and `rgba(204,214,235,0.25)` for category axes, where
|
|
* the crosshair by default highlights the whole category.
|
|
*
|
|
* @sample {highcharts|highstock|highmaps} highcharts/xaxis/crosshair-customized/
|
|
* Customized crosshairs
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @default #cccccc
|
|
* @since 4.1
|
|
* @apioption xAxis.crosshair.color
|
|
*/
|
|
/**
|
|
* The dash style for the crosshair. See
|
|
* [plotOptions.series.dashStyle](#plotOptions.series.dashStyle)
|
|
* for possible values.
|
|
*
|
|
* @sample {highcharts|highmaps} highcharts/xaxis/crosshair-dotted/
|
|
* Dotted crosshair
|
|
* @sample {highstock} stock/xaxis/crosshair-dashed/
|
|
* Dashed X axis crosshair
|
|
*
|
|
* @type {Highcharts.DashStyleValue}
|
|
* @default Solid
|
|
* @since 4.1
|
|
* @apioption xAxis.crosshair.dashStyle
|
|
*/
|
|
/**
|
|
* A label on the axis next to the crosshair.
|
|
*
|
|
* In styled mode, the label is styled with the
|
|
* `.highcharts-crosshair-label` class.
|
|
*
|
|
* @sample {highstock} stock/xaxis/crosshair-label/
|
|
* Crosshair labels
|
|
* @sample {highstock} highcharts/css/crosshair-label/
|
|
* Style mode
|
|
*
|
|
* @declare Highcharts.AxisCrosshairLabelOptions
|
|
* @since 2.1
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label
|
|
*/
|
|
/**
|
|
* Alignment of the label compared to the axis. Defaults to `"left"` for
|
|
* right-side axes, `"right"` for left-side axes and `"center"` for
|
|
* horizontal axes.
|
|
*
|
|
* @type {Highcharts.AlignValue}
|
|
* @since 2.1
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label.align
|
|
*/
|
|
/**
|
|
* The background color for the label. Defaults to the related series
|
|
* color, or `#666666` if that is not available.
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @since 2.1
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label.backgroundColor
|
|
*/
|
|
/**
|
|
* The border color for the crosshair label
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @since 2.1
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label.borderColor
|
|
*/
|
|
/**
|
|
* The border corner radius of the crosshair label.
|
|
*
|
|
* @type {number}
|
|
* @default 3
|
|
* @since 2.1.10
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label.borderRadius
|
|
*/
|
|
/**
|
|
* The border width for the crosshair label.
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 2.1
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label.borderWidth
|
|
*/
|
|
/**
|
|
* Flag to enable crosshair's label.
|
|
*
|
|
* @sample {highstock} stock/xaxis/crosshairs-xy/
|
|
* Enabled label for yAxis' crosshair
|
|
*
|
|
* @type {boolean}
|
|
* @default false
|
|
* @since 2.1
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label.enabled
|
|
*/
|
|
/**
|
|
* A format string for the crosshair label. Defaults to `{value}` for
|
|
* numeric axes and `{value:%b %d, %Y}` for datetime axes.
|
|
*
|
|
* @type {string}
|
|
* @since 2.1
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label.format
|
|
*/
|
|
/**
|
|
* Formatter function for the label text.
|
|
*
|
|
* @type {Highcharts.XAxisCrosshairLabelFormatterCallbackFunction}
|
|
* @since 2.1
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label.formatter
|
|
*/
|
|
/**
|
|
* Padding inside the crosshair label.
|
|
*
|
|
* @type {number}
|
|
* @default 8
|
|
* @since 2.1
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label.padding
|
|
*/
|
|
/**
|
|
* The shape to use for the label box.
|
|
*
|
|
* @type {string}
|
|
* @default callout
|
|
* @since 2.1
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label.shape
|
|
*/
|
|
/**
|
|
* Text styles for the crosshair label.
|
|
*
|
|
* @type {Highcharts.CSSObject}
|
|
* @default {"color": "white", "fontWeight": "normal", "fontSize": "11px", "textAlign": "center"}
|
|
* @since 2.1
|
|
* @product highstock
|
|
* @apioption xAxis.crosshair.label.style
|
|
*/
|
|
/**
|
|
* Whether the crosshair should snap to the point or follow the pointer
|
|
* independent of points.
|
|
*
|
|
* @sample {highcharts|highstock} highcharts/xaxis/crosshair-snap-false/
|
|
* True by default
|
|
* @sample {highmaps} maps/demo/latlon-advanced/
|
|
* Snap is false
|
|
*
|
|
* @type {boolean}
|
|
* @default true
|
|
* @since 4.1
|
|
* @apioption xAxis.crosshair.snap
|
|
*/
|
|
/**
|
|
* The pixel width of the crosshair. Defaults to 1 for numeric or
|
|
* datetime axes, and for one category width for category axes.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/crosshair-customized/
|
|
* Customized crosshairs
|
|
* @sample {highstock} highcharts/xaxis/crosshair-customized/
|
|
* Customized crosshairs
|
|
* @sample {highmaps} highcharts/xaxis/crosshair-customized/
|
|
* Customized crosshairs
|
|
*
|
|
* @type {number}
|
|
* @default 1
|
|
* @since 4.1
|
|
* @apioption xAxis.crosshair.width
|
|
*/
|
|
/**
|
|
* The Z index of the crosshair. Higher Z indices allow drawing the
|
|
* crosshair on top of the series or behind the grid lines.
|
|
*
|
|
* @type {number}
|
|
* @default 2
|
|
* @since 4.1
|
|
* @apioption xAxis.crosshair.zIndex
|
|
*/
|
|
/**
|
|
* Whether to zoom axis. If `chart.zoomType` is set, the option allows
|
|
* to disable zooming on an individual axis.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/zoomenabled/
|
|
* Zoom enabled is false
|
|
*
|
|
*
|
|
* @type {boolean}
|
|
* @default enabled
|
|
* @apioption xAxis.zoomEnabled
|
|
*/
|
|
/**
|
|
* For a datetime axis, the scale will automatically adjust to the
|
|
* appropriate unit. This member gives the default string
|
|
* representations used for each unit. For intermediate values,
|
|
* different units may be used, for example the `day` unit can be used
|
|
* on midnight and `hour` unit be used for intermediate values on the
|
|
* same axis. For an overview of the replacement codes, see
|
|
* [dateFormat](/class-reference/Highcharts#dateFormat).
|
|
*
|
|
* Defaults to:
|
|
* ```js
|
|
* {
|
|
* millisecond: '%H:%M:%S.%L',
|
|
* second: '%H:%M:%S',
|
|
* minute: '%H:%M',
|
|
* hour: '%H:%M',
|
|
* day: '%e. %b',
|
|
* week: '%e. %b',
|
|
* month: '%b \'%y',
|
|
* year: '%Y'
|
|
* }
|
|
* ```
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/datetimelabelformats/
|
|
* Different day format on X axis
|
|
* @sample {highstock} stock/xaxis/datetimelabelformats/
|
|
* More information in x axis labels
|
|
*
|
|
* @declare Highcharts.AxisDateTimeLabelFormatsOptions
|
|
* @product highcharts highstock gantt
|
|
*/
|
|
dateTimeLabelFormats: {
|
|
/**
|
|
* @declare Highcharts.AxisDateTimeLabelFormatsOptionsObject
|
|
* @type {string|*}
|
|
*/
|
|
millisecond: {
|
|
main: '%H:%M:%S.%L',
|
|
range: false
|
|
},
|
|
/**
|
|
* @declare Highcharts.AxisDateTimeLabelFormatsOptionsObject
|
|
* @type {string|*}
|
|
*/
|
|
second: {
|
|
main: '%H:%M:%S',
|
|
range: false
|
|
},
|
|
/**
|
|
* @declare Highcharts.AxisDateTimeLabelFormatsOptionsObject
|
|
* @type {string|*}
|
|
*/
|
|
minute: {
|
|
main: '%H:%M',
|
|
range: false
|
|
},
|
|
/**
|
|
* @declare Highcharts.AxisDateTimeLabelFormatsOptionsObject
|
|
* @type {string|*}
|
|
*/
|
|
hour: {
|
|
main: '%H:%M',
|
|
range: false
|
|
},
|
|
/**
|
|
* @declare Highcharts.AxisDateTimeLabelFormatsOptionsObject
|
|
* @type {string|*}
|
|
*/
|
|
day: {
|
|
main: '%e. %b'
|
|
},
|
|
/**
|
|
* @declare Highcharts.AxisDateTimeLabelFormatsOptionsObject
|
|
* @type {string|*}
|
|
*/
|
|
week: {
|
|
main: '%e. %b'
|
|
},
|
|
/**
|
|
* @declare Highcharts.AxisDateTimeLabelFormatsOptionsObject
|
|
* @type {string|*}
|
|
*/
|
|
month: {
|
|
main: '%b \'%y'
|
|
},
|
|
/**
|
|
* @declare Highcharts.AxisDateTimeLabelFormatsOptionsObject
|
|
* @type {string|*}
|
|
*/
|
|
year: {
|
|
main: '%Y'
|
|
}
|
|
},
|
|
/**
|
|
* Whether to force the axis to end on a tick. Use this option with
|
|
* the `maxPadding` option to control the axis end.
|
|
*
|
|
* @productdesc {highstock}
|
|
* In Highstock, `endOnTick` is always `false` when the navigator
|
|
* is enabled, to prevent jumpy scrolling.
|
|
*
|
|
* @sample {highcharts} highcharts/chart/reflow-true/
|
|
* True by default
|
|
* @sample {highcharts} highcharts/yaxis/endontick/
|
|
* False
|
|
* @sample {highstock} stock/demo/basic-line/
|
|
* True by default
|
|
* @sample {highstock} stock/xaxis/endontick/
|
|
* False
|
|
*
|
|
* @since 1.2.0
|
|
*/
|
|
endOnTick: false,
|
|
/**
|
|
* Event handlers for the axis.
|
|
*
|
|
* @type {*}
|
|
* @apioption xAxis.events
|
|
*/
|
|
/**
|
|
* An event fired after the breaks have rendered.
|
|
*
|
|
* @see [breaks](#xAxis.breaks)
|
|
*
|
|
* @sample {highcharts} highcharts/axisbreak/break-event/
|
|
* AfterBreak Event
|
|
*
|
|
* @type {Highcharts.AxisEventCallbackFunction}
|
|
* @since 4.1.0
|
|
* @product highcharts gantt
|
|
* @apioption xAxis.events.afterBreaks
|
|
*/
|
|
/**
|
|
* As opposed to the `setExtremes` event, this event fires after the
|
|
* final min and max values are computed and corrected for `minRange`.
|
|
*
|
|
* Fires when the minimum and maximum is set for the axis, either by
|
|
* calling the `.setExtremes()` method or by selecting an area in the
|
|
* chart. One parameter, `event`, is passed to the function, containing
|
|
* common event information.
|
|
*
|
|
* The new user set minimum and maximum values can be found by
|
|
* `event.min` and `event.max`. These reflect the axis minimum and
|
|
* maximum in axis values. The actual data extremes are found in
|
|
* `event.dataMin` and `event.dataMax`.
|
|
*
|
|
* @type {Highcharts.AxisSetExtremesEventCallbackFunction}
|
|
* @since 2.3
|
|
* @context Highcharts.Axis
|
|
* @apioption xAxis.events.afterSetExtremes
|
|
*/
|
|
/**
|
|
* An event fired when a break from this axis occurs on a point.
|
|
*
|
|
* @see [breaks](#xAxis.breaks)
|
|
*
|
|
* @sample {highcharts} highcharts/axisbreak/break-visualized/
|
|
* Visualization of a Break
|
|
*
|
|
* @type {Highcharts.AxisPointBreakEventCallbackFunction}
|
|
* @since 4.1.0
|
|
* @product highcharts gantt
|
|
* @context Highcharts.Axis
|
|
* @apioption xAxis.events.pointBreak
|
|
*/
|
|
/**
|
|
* An event fired when a point falls inside a break from this axis.
|
|
*
|
|
* @type {Highcharts.AxisPointBreakEventCallbackFunction}
|
|
* @product highcharts highstock gantt
|
|
* @context Highcharts.Axis
|
|
* @apioption xAxis.events.pointInBreak
|
|
*/
|
|
/**
|
|
* Fires when the minimum and maximum is set for the axis, either by
|
|
* calling the `.setExtremes()` method or by selecting an area in the
|
|
* chart. One parameter, `event`, is passed to the function,
|
|
* containing common event information.
|
|
*
|
|
* The new user set minimum and maximum values can be found by
|
|
* `event.min` and `event.max`. These reflect the axis minimum and
|
|
* maximum in data values. When an axis is zoomed all the way out from
|
|
* the "Reset zoom" button, `event.min` and `event.max` are null, and
|
|
* the new extremes are set based on `this.dataMin` and `this.dataMax`.
|
|
*
|
|
* @sample {highstock} stock/xaxis/events-setextremes/
|
|
* Log new extremes on x axis
|
|
*
|
|
* @type {Highcharts.AxisSetExtremesEventCallbackFunction}
|
|
* @since 1.2.0
|
|
* @context Highcharts.Axis
|
|
* @apioption xAxis.events.setExtremes
|
|
*/
|
|
/**
|
|
* The lowest allowed value for automatically computed axis extremes.
|
|
*
|
|
* @see [ceiling](#yAxis.ceiling)
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/floor-ceiling/
|
|
* Floor and ceiling
|
|
* @sample {highstock} stock/demo/lazy-loading/
|
|
* Prevent negative stock price on Y axis
|
|
*
|
|
* @type {number}
|
|
* @since 4.0
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.floor
|
|
*/
|
|
/**
|
|
* The dash or dot style of the grid lines. For possible values, see
|
|
* [this demonstration](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-dashstyle-all/).
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/gridlinedashstyle/
|
|
* Long dashes
|
|
* @sample {highstock} stock/xaxis/gridlinedashstyle/
|
|
* Long dashes
|
|
*
|
|
* @type {Highcharts.DashStyleValue}
|
|
* @default Solid
|
|
* @since 1.2
|
|
* @apioption xAxis.gridLineDashStyle
|
|
*/
|
|
/**
|
|
* The Z index of the grid lines.
|
|
*
|
|
* @sample {highcharts|highstock} highcharts/xaxis/gridzindex/
|
|
* A Z index of 4 renders the grid above the graph
|
|
*
|
|
* @type {number}
|
|
* @default 1
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.gridZIndex
|
|
*/
|
|
/**
|
|
* An id for the axis. This can be used after render time to get
|
|
* a pointer to the axis object through `chart.get()`.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/id/
|
|
* Get the object
|
|
* @sample {highstock} stock/xaxis/id/
|
|
* Get the object
|
|
*
|
|
* @type {string}
|
|
* @since 1.2.0
|
|
* @apioption xAxis.id
|
|
*/
|
|
/**
|
|
* The axis labels show the number or category for each tick.
|
|
*
|
|
* Since v8.0.0: Labels are animated in categorized x-axis with
|
|
* updating data if `tickInterval` and `step` is set to 1.
|
|
*
|
|
* @productdesc {highmaps}
|
|
* X and Y axis labels are by default disabled in Highmaps, but the
|
|
* functionality is inherited from Highcharts and used on `colorAxis`,
|
|
* and can be enabled on X and Y axes too.
|
|
*/
|
|
labels: {
|
|
/**
|
|
* What part of the string the given position is anchored to.
|
|
* If `left`, the left side of the string is at the axis position.
|
|
* Can be one of `"left"`, `"center"` or `"right"`. Defaults to
|
|
* an intelligent guess based on which side of the chart the axis
|
|
* is on and the rotation of the label.
|
|
*
|
|
* @see [reserveSpace](#xAxis.labels.reserveSpace)
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-align-left/
|
|
* Left
|
|
* @sample {highcharts} highcharts/xaxis/labels-align-right/
|
|
* Right
|
|
* @sample {highcharts} highcharts/xaxis/labels-reservespace-true/
|
|
* Left-aligned labels on a vertical category axis
|
|
*
|
|
* @type {Highcharts.AlignValue}
|
|
* @apioption xAxis.labels.align
|
|
*/
|
|
/**
|
|
* For horizontal axes, the allowed degrees of label rotation
|
|
* to prevent overlapping labels. If there is enough space,
|
|
* labels are not rotated. As the chart gets narrower, it
|
|
* will start rotating the labels -45 degrees, then remove
|
|
* every second label and try again with rotations 0 and -45 etc.
|
|
* Set it to `false` to disable rotation, which will
|
|
* cause the labels to word-wrap if possible.
|
|
*
|
|
* @sample {highcharts|highstock} highcharts/xaxis/labels-autorotation-default/
|
|
* Default auto rotation of 0 or -45
|
|
* @sample {highcharts|highstock} highcharts/xaxis/labels-autorotation-0-90/
|
|
* Custom graded auto rotation
|
|
*
|
|
* @type {Array<number>|false}
|
|
* @default [-45]
|
|
* @since 4.1.0
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.labels.autoRotation
|
|
*/
|
|
/**
|
|
* When each category width is more than this many pixels, we don't
|
|
* apply auto rotation. Instead, we lay out the axis label with word
|
|
* wrap. A lower limit makes sense when the label contains multiple
|
|
* short words that don't extend the available horizontal space for
|
|
* each label.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-autorotationlimit/
|
|
* Lower limit
|
|
*
|
|
* @type {number}
|
|
* @default 80
|
|
* @since 4.1.5
|
|
* @product highcharts gantt
|
|
* @apioption xAxis.labels.autoRotationLimit
|
|
*/
|
|
/**
|
|
* Polar charts only. The label's pixel distance from the perimeter
|
|
* of the plot area.
|
|
*
|
|
* @type {number}
|
|
* @default 15
|
|
* @product highcharts gantt
|
|
* @apioption xAxis.labels.distance
|
|
*/
|
|
/**
|
|
* Enable or disable the axis labels.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-enabled/
|
|
* X axis labels disabled
|
|
* @sample {highstock} stock/xaxis/labels-enabled/
|
|
* X axis labels disabled
|
|
*
|
|
* @default {highcharts|highstock|gantt} true
|
|
* @default {highmaps} false
|
|
*/
|
|
enabled: true,
|
|
/**
|
|
* A [format string](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting)
|
|
* for the axis label.
|
|
*
|
|
* @sample {highcharts|highstock} highcharts/yaxis/labels-format/
|
|
* Add units to Y axis label
|
|
*
|
|
* @type {string}
|
|
* @default {value}
|
|
* @since 3.0
|
|
* @apioption xAxis.labels.format
|
|
*/
|
|
/**
|
|
* Callback JavaScript function to format the label. The value
|
|
* is given by `this.value`. Additional properties for `this` are
|
|
* `axis`, `chart`, `isFirst` and `isLast`. The value of the default
|
|
* label formatter can be retrieved by calling
|
|
* `this.axis.defaultLabelFormatter.call(this)` within the function.
|
|
*
|
|
* Defaults to:
|
|
* ```js
|
|
* function() {
|
|
* return this.value;
|
|
* }
|
|
* ```
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-formatter-linked/
|
|
* Linked category names
|
|
* @sample {highcharts} highcharts/xaxis/labels-formatter-extended/
|
|
* Modified numeric labels
|
|
* @sample {highstock} stock/xaxis/labels-formatter/
|
|
* Added units on Y axis
|
|
*
|
|
* @type {Highcharts.FormatterCallbackFunction<Highcharts.AxisLabelsFormatterContextObject>}
|
|
* @apioption xAxis.labels.formatter
|
|
*/
|
|
/**
|
|
* The number of pixels to indent the labels per level in a treegrid
|
|
* axis.
|
|
*
|
|
* @sample gantt/treegrid-axis/demo
|
|
* Indentation 10px by default.
|
|
* @sample gantt/treegrid-axis/indentation-0px
|
|
* Indentation set to 0px.
|
|
*
|
|
* @product gantt
|
|
*/
|
|
indentation: 10,
|
|
/**
|
|
* Horizontal axis only. When `staggerLines` is not set,
|
|
* `maxStaggerLines` defines how many lines the axis is allowed to
|
|
* add to automatically avoid overlapping X labels. Set to `1` to
|
|
* disable overlap detection.
|
|
*
|
|
* @deprecated
|
|
* @type {number}
|
|
* @default 5
|
|
* @since 1.3.3
|
|
* @apioption xAxis.labels.maxStaggerLines
|
|
*/
|
|
/**
|
|
* How to handle overflowing labels on horizontal axis. If set to
|
|
* `"allow"`, it will not be aligned at all. By default it
|
|
* `"justify"` labels inside the chart area. If there is room to
|
|
* move it, it will be aligned to the edge, else it will be removed.
|
|
*
|
|
* @type {string}
|
|
* @default justify
|
|
* @since 2.2.5
|
|
* @validvalue ["allow", "justify"]
|
|
* @apioption xAxis.labels.overflow
|
|
*/
|
|
/**
|
|
* The pixel padding for axis labels, to ensure white space between
|
|
* them.
|
|
*
|
|
* @type {number}
|
|
* @default 5
|
|
* @product highcharts gantt
|
|
* @apioption xAxis.labels.padding
|
|
*/
|
|
/**
|
|
* Whether to reserve space for the labels. By default, space is
|
|
* reserved for the labels in these cases:
|
|
*
|
|
* * On all horizontal axes.
|
|
* * On vertical axes if `label.align` is `right` on a left-side
|
|
* axis or `left` on a right-side axis.
|
|
* * On vertical axes if `label.align` is `center`.
|
|
*
|
|
* This can be turned off when for example the labels are rendered
|
|
* inside the plot area instead of outside.
|
|
*
|
|
* @see [labels.align](#xAxis.labels.align)
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-reservespace/
|
|
* No reserved space, labels inside plot
|
|
* @sample {highcharts} highcharts/xaxis/labels-reservespace-true/
|
|
* Left-aligned labels on a vertical category axis
|
|
*
|
|
* @type {boolean}
|
|
* @since 4.1.10
|
|
* @product highcharts gantt
|
|
* @apioption xAxis.labels.reserveSpace
|
|
*/
|
|
/**
|
|
* Rotation of the labels in degrees.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-rotation/
|
|
* X axis labels rotated 90°
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @apioption xAxis.labels.rotation
|
|
*/
|
|
/**
|
|
* Horizontal axes only. The number of lines to spread the labels
|
|
* over to make room or tighter labels.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-staggerlines/
|
|
* Show labels over two lines
|
|
* @sample {highstock} stock/xaxis/labels-staggerlines/
|
|
* Show labels over two lines
|
|
*
|
|
* @type {number}
|
|
* @since 2.1
|
|
* @apioption xAxis.labels.staggerLines
|
|
*/
|
|
/**
|
|
* To show only every _n_'th label on the axis, set the step to _n_.
|
|
* Setting the step to 2 shows every other label.
|
|
*
|
|
* By default, the step is calculated automatically to avoid
|
|
* overlap. To prevent this, set it to 1\. This usually only
|
|
* happens on a category axis, and is often a sign that you have
|
|
* chosen the wrong axis type.
|
|
*
|
|
* Read more at
|
|
* [Axis docs](https://www.highcharts.com/docs/chart-concepts/axes)
|
|
* => What axis should I use?
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-step/
|
|
* Showing only every other axis label on a categorized
|
|
* x-axis
|
|
* @sample {highcharts} highcharts/xaxis/labels-step-auto/
|
|
* Auto steps on a category axis
|
|
*
|
|
* @type {number}
|
|
* @since 2.1
|
|
* @apioption xAxis.labels.step
|
|
*/
|
|
/**
|
|
* Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)
|
|
* to render the labels.
|
|
*
|
|
* @type {boolean}
|
|
* @default false
|
|
* @apioption xAxis.labels.useHTML
|
|
*/
|
|
/**
|
|
* The x position offset of the label relative to the tick position
|
|
* on the axis.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-x/
|
|
* Y axis labels placed on grid lines
|
|
*/
|
|
x: 0,
|
|
/**
|
|
* The y position offset of the label relative to the tick position
|
|
* on the axis. The default makes it adapt to the font size on
|
|
* bottom axis.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-x/
|
|
* Y axis labels placed on grid lines
|
|
*
|
|
* @type {number}
|
|
* @apioption xAxis.labels.y
|
|
*/
|
|
/**
|
|
* The Z index for the axis labels.
|
|
*
|
|
* @type {number}
|
|
* @default 7
|
|
* @apioption xAxis.labels.zIndex
|
|
*/
|
|
/**
|
|
* CSS styles for the label. Use `whiteSpace: 'nowrap'` to prevent
|
|
* wrapping of category labels. Use `textOverflow: 'none'` to
|
|
* prevent ellipsis (dots).
|
|
*
|
|
* In styled mode, the labels are styled with the
|
|
* `.highcharts-axis-labels` class.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-style/
|
|
* Red X axis labels
|
|
*
|
|
* @type {Highcharts.CSSObject}
|
|
*/
|
|
style: {
|
|
/** @internal */
|
|
color: '#666666',
|
|
/** @internal */
|
|
cursor: 'default',
|
|
/** @internal */
|
|
fontSize: '11px'
|
|
}
|
|
},
|
|
/**
|
|
* The left position as the horizontal axis. If it's a number, it is
|
|
* interpreted as pixel position relative to the chart.
|
|
*
|
|
* Since Highcharts v5.0.13: If it's a percentage string, it is
|
|
* interpreted as percentages of the plot width, offset from plot area
|
|
* left.
|
|
*
|
|
* @type {number|string}
|
|
* @product highcharts highstock
|
|
* @apioption xAxis.left
|
|
*/
|
|
/**
|
|
* The top position as the vertical axis. If it's a number, it is
|
|
* interpreted as pixel position relative to the chart.
|
|
*
|
|
* Since Highcharts 2: If it's a percentage string, it is interpreted
|
|
* as percentages of the plot height, offset from plot area top.
|
|
*
|
|
* @type {number|string}
|
|
* @product highcharts highstock
|
|
* @apioption xAxis.top
|
|
*/
|
|
/**
|
|
* Index of another axis that this axis is linked to. When an axis is
|
|
* linked to a master axis, it will take the same extremes as
|
|
* the master, but as assigned by min or max or by setExtremes.
|
|
* It can be used to show additional info, or to ease reading the
|
|
* chart by duplicating the scales.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/linkedto/
|
|
* Different string formats of the same date
|
|
* @sample {highcharts} highcharts/yaxis/linkedto/
|
|
* Y values on both sides
|
|
*
|
|
* @type {number}
|
|
* @since 2.0.2
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.linkedTo
|
|
*/
|
|
/**
|
|
* The maximum value of the axis. If `null`, the max value is
|
|
* automatically calculated.
|
|
*
|
|
* If the [endOnTick](#yAxis.endOnTick) option is true, the `max` value
|
|
* might be rounded up.
|
|
*
|
|
* If a [tickAmount](#yAxis.tickAmount) is set, the axis may be extended
|
|
* beyond the set max in order to reach the given number of ticks. The
|
|
* same may happen in a chart with multiple axes, determined by [chart.
|
|
* alignTicks](#chart), where a `tickAmount` is applied internally.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/max-200/
|
|
* Y axis max of 200
|
|
* @sample {highcharts} highcharts/yaxis/max-logarithmic/
|
|
* Y axis max on logarithmic axis
|
|
* @sample {highstock} stock/xaxis/min-max/
|
|
* Fixed min and max on X axis
|
|
* @sample {highmaps} maps/axis/min-max/
|
|
* Pre-zoomed to a specific area
|
|
*
|
|
* @type {number|null}
|
|
* @apioption xAxis.max
|
|
*/
|
|
/**
|
|
* Padding of the max value relative to the length of the axis. A
|
|
* padding of 0.05 will make a 100px axis 5px longer. This is useful
|
|
* when you don't want the highest data value to appear on the edge
|
|
* of the plot area. When the axis' `max` option is set or a max extreme
|
|
* is set using `axis.setExtremes()`, the maxPadding will be ignored.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/maxpadding/
|
|
* Max padding of 0.25 on y axis
|
|
* @sample {highstock} stock/xaxis/minpadding-maxpadding/
|
|
* Greater min- and maxPadding
|
|
* @sample {highmaps} maps/chart/plotbackgroundcolor-gradient/
|
|
* Add some padding
|
|
*
|
|
* @default {highcharts} 0.01
|
|
* @default {highstock|highmaps} 0
|
|
* @since 1.2.0
|
|
*/
|
|
maxPadding: 0.01,
|
|
/**
|
|
* Deprecated. Use `minRange` instead.
|
|
*
|
|
* @deprecated
|
|
* @type {number}
|
|
* @product highcharts highstock
|
|
* @apioption xAxis.maxZoom
|
|
*/
|
|
/**
|
|
* The minimum value of the axis. If `null` the min value is
|
|
* automatically calculated.
|
|
*
|
|
* If the [startOnTick](#yAxis.startOnTick) option is true (default),
|
|
* the `min` value might be rounded down.
|
|
*
|
|
* The automatically calculated minimum value is also affected by
|
|
* [floor](#yAxis.floor), [softMin](#yAxis.softMin),
|
|
* [minPadding](#yAxis.minPadding), [minRange](#yAxis.minRange)
|
|
* as well as [series.threshold](#plotOptions.series.threshold)
|
|
* and [series.softThreshold](#plotOptions.series.softThreshold).
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/min-startontick-false/
|
|
* -50 with startOnTick to false
|
|
* @sample {highcharts} highcharts/yaxis/min-startontick-true/
|
|
* -50 with startOnTick true by default
|
|
* @sample {highstock} stock/xaxis/min-max/
|
|
* Set min and max on X axis
|
|
* @sample {highmaps} maps/axis/min-max/
|
|
* Pre-zoomed to a specific area
|
|
*
|
|
* @type {number|null}
|
|
* @apioption xAxis.min
|
|
*/
|
|
/**
|
|
* The dash or dot style of the minor grid lines. For possible values,
|
|
* see [this demonstration](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-dashstyle-all/).
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/minorgridlinedashstyle/
|
|
* Long dashes on minor grid lines
|
|
* @sample {highstock} stock/xaxis/minorgridlinedashstyle/
|
|
* Long dashes on minor grid lines
|
|
*
|
|
* @type {Highcharts.DashStyleValue}
|
|
* @default Solid
|
|
* @since 1.2
|
|
* @apioption xAxis.minorGridLineDashStyle
|
|
*/
|
|
/**
|
|
* Specific tick interval in axis units for the minor ticks. On a linear
|
|
* axis, if `"auto"`, the minor tick interval is calculated as a fifth
|
|
* of the tickInterval. If `null` or `undefined`, minor ticks are not
|
|
* shown.
|
|
*
|
|
* On logarithmic axes, the unit is the power of the value. For example,
|
|
* setting the minorTickInterval to 1 puts one tick on each of 0.1, 1,
|
|
* 10, 100 etc. Setting the minorTickInterval to 0.1 produces 9 ticks
|
|
* between 1 and 10, 10 and 100 etc.
|
|
*
|
|
* If user settings dictate minor ticks to become too dense, they don't
|
|
* make sense, and will be ignored to prevent performance problems.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/minortickinterval-null/
|
|
* Null by default
|
|
* @sample {highcharts} highcharts/yaxis/minortickinterval-5/
|
|
* 5 units
|
|
* @sample {highcharts} highcharts/yaxis/minortickinterval-log-auto/
|
|
* "auto"
|
|
* @sample {highcharts} highcharts/yaxis/minortickinterval-log/
|
|
* 0.1
|
|
* @sample {highstock} stock/demo/basic-line/
|
|
* Null by default
|
|
* @sample {highstock} stock/xaxis/minortickinterval-auto/
|
|
* "auto"
|
|
*
|
|
* @type {number|string|null}
|
|
* @apioption xAxis.minorTickInterval
|
|
*/
|
|
/**
|
|
* The pixel length of the minor tick marks.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/minorticklength/
|
|
* 10px on Y axis
|
|
* @sample {highstock} stock/xaxis/minorticks/
|
|
* 10px on Y axis
|
|
*/
|
|
minorTickLength: 2,
|
|
/**
|
|
* The position of the minor tick marks relative to the axis line.
|
|
* Can be one of `inside` and `outside`.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/minortickposition-outside/
|
|
* Outside by default
|
|
* @sample {highcharts} highcharts/yaxis/minortickposition-inside/
|
|
* Inside
|
|
* @sample {highstock} stock/xaxis/minorticks/
|
|
* Inside
|
|
*
|
|
* @validvalue ["inside", "outside"]
|
|
*/
|
|
minorTickPosition: 'outside',
|
|
/**
|
|
* Enable or disable minor ticks. Unless
|
|
* [minorTickInterval](#xAxis.minorTickInterval) is set, the tick
|
|
* interval is calculated as a fifth of the `tickInterval`.
|
|
*
|
|
* On a logarithmic axis, minor ticks are laid out based on a best
|
|
* guess, attempting to enter approximately 5 minor ticks between
|
|
* each major tick.
|
|
*
|
|
* Prior to v6.0.0, ticks were unabled in auto layout by setting
|
|
* `minorTickInterval` to `"auto"`.
|
|
*
|
|
* @productdesc {highcharts}
|
|
* On axes using [categories](#xAxis.categories), minor ticks are not
|
|
* supported.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/minorticks-true/
|
|
* Enabled on linear Y axis
|
|
*
|
|
* @type {boolean}
|
|
* @default false
|
|
* @since 6.0.0
|
|
* @apioption xAxis.minorTicks
|
|
*/
|
|
/**
|
|
* The pixel width of the minor tick mark.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/minortickwidth/
|
|
* 3px width
|
|
* @sample {highstock} stock/xaxis/minorticks/
|
|
* 1px width
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @apioption xAxis.minorTickWidth
|
|
*/
|
|
/**
|
|
* Padding of the min value relative to the length of the axis. A
|
|
* padding of 0.05 will make a 100px axis 5px longer. This is useful
|
|
* when you don't want the lowest data value to appear on the edge
|
|
* of the plot area. When the axis' `min` option is set or a min extreme
|
|
* is set using `axis.setExtremes()`, the minPadding will be ignored.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/minpadding/
|
|
* Min padding of 0.2
|
|
* @sample {highstock} stock/xaxis/minpadding-maxpadding/
|
|
* Greater min- and maxPadding
|
|
* @sample {highmaps} maps/chart/plotbackgroundcolor-gradient/
|
|
* Add some padding
|
|
*
|
|
* @default {highcharts} 0.01
|
|
* @default {highstock|highmaps} 0
|
|
* @since 1.2.0
|
|
* @product highcharts highstock gantt
|
|
*/
|
|
minPadding: 0.01,
|
|
/**
|
|
* The minimum range to display on this axis. The entire axis will not
|
|
* be allowed to span over a smaller interval than this. For example,
|
|
* for a datetime axis the main unit is milliseconds. If minRange is
|
|
* set to 3600000, you can't zoom in more than to one hour.
|
|
*
|
|
* The default minRange for the x axis is five times the smallest
|
|
* interval between any of the data points.
|
|
*
|
|
* On a logarithmic axis, the unit for the minimum range is the power.
|
|
* So a minRange of 1 means that the axis can be zoomed to 10-100,
|
|
* 100-1000, 1000-10000 etc.
|
|
*
|
|
* Note that the `minPadding`, `maxPadding`, `startOnTick` and
|
|
* `endOnTick` settings also affect how the extremes of the axis
|
|
* are computed.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/minrange/
|
|
* Minimum range of 5
|
|
* @sample {highstock} stock/xaxis/minrange/
|
|
* Max zoom of 6 months overrides user selections
|
|
* @sample {highmaps} maps/axis/minrange/
|
|
* Minimum range of 1000
|
|
*
|
|
* @type {number}
|
|
* @apioption xAxis.minRange
|
|
*/
|
|
/**
|
|
* The minimum tick interval allowed in axis values. For example on
|
|
* zooming in on an axis with daily data, this can be used to prevent
|
|
* the axis from showing hours. Defaults to the closest distance between
|
|
* two points on the axis.
|
|
*
|
|
* @type {number}
|
|
* @since 2.3.0
|
|
* @apioption xAxis.minTickInterval
|
|
*/
|
|
/**
|
|
* The distance in pixels from the plot area to the axis line.
|
|
* A positive offset moves the axis with it's line, labels and ticks
|
|
* away from the plot area. This is typically used when two or more
|
|
* axes are displayed on the same side of the plot. With multiple
|
|
* axes the offset is dynamically adjusted to avoid collision, this
|
|
* can be overridden by setting offset explicitly.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/offset/
|
|
* Y axis offset of 70
|
|
* @sample {highcharts} highcharts/yaxis/offset-centered/
|
|
* Axes positioned in the center of the plot
|
|
* @sample {highstock} stock/xaxis/offset/
|
|
* Y axis offset by 70 px
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @apioption xAxis.offset
|
|
*/
|
|
/**
|
|
* Whether to display the axis on the opposite side of the normal. The
|
|
* normal is on the left side for vertical axes and bottom for
|
|
* horizontal, so the opposite sides will be right and top respectively.
|
|
* This is typically used with dual or multiple axes.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/opposite/
|
|
* Secondary Y axis opposite
|
|
* @sample {highstock} stock/xaxis/opposite/
|
|
* Y axis on left side
|
|
*
|
|
* @type {boolean}
|
|
* @default false
|
|
* @apioption xAxis.opposite
|
|
*/
|
|
/**
|
|
* In an ordinal axis, the points are equally spaced in the chart
|
|
* regardless of the actual time or x distance between them. This means
|
|
* that missing data periods (e.g. nights or weekends for a stock chart)
|
|
* will not take up space in the chart.
|
|
* Having `ordinal: false` will show any gaps created by the `gapSize`
|
|
* setting proportionate to their duration.
|
|
*
|
|
* In stock charts the X axis is ordinal by default, unless
|
|
* the boost module is used and at least one of the series' data length
|
|
* exceeds the [boostThreshold](#series.line.boostThreshold).
|
|
*
|
|
* @sample {highstock} stock/xaxis/ordinal-true/
|
|
* True by default
|
|
* @sample {highstock} stock/xaxis/ordinal-false/
|
|
* False
|
|
*
|
|
* @type {boolean}
|
|
* @default true
|
|
* @since 1.1
|
|
* @product highstock
|
|
* @apioption xAxis.ordinal
|
|
*/
|
|
/**
|
|
* Additional range on the right side of the xAxis. Works similar to
|
|
* `xAxis.maxPadding`, but value is set in milliseconds. Can be set for
|
|
* both main `xAxis` and the navigator's `xAxis`.
|
|
*
|
|
* @sample {highstock} stock/xaxis/overscroll/
|
|
* One minute overscroll with live data
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 6.0.0
|
|
* @product highstock
|
|
* @apioption xAxis.overscroll
|
|
*/
|
|
/**
|
|
* Refers to the index in the [panes](#panes) array. Used for circular
|
|
* gauges and polar charts. When the option is not set then first pane
|
|
* will be used.
|
|
*
|
|
* @sample highcharts/demo/gauge-vu-meter
|
|
* Two gauges with different center
|
|
*
|
|
* @type {number}
|
|
* @product highcharts
|
|
* @apioption xAxis.pane
|
|
*/
|
|
/**
|
|
* The zoomed range to display when only defining one or none of `min`
|
|
* or `max`. For example, to show the latest month, a range of one month
|
|
* can be set.
|
|
*
|
|
* @sample {highstock} stock/xaxis/range/
|
|
* Setting a zoomed range when the rangeSelector is disabled
|
|
*
|
|
* @type {number}
|
|
* @product highstock
|
|
* @apioption xAxis.range
|
|
*/
|
|
/**
|
|
* Whether to reverse the axis so that the highest number is closest
|
|
* to the origin. If the chart is inverted, the x axis is reversed by
|
|
* default.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/reversed/
|
|
* Reversed Y axis
|
|
* @sample {highstock} stock/xaxis/reversed/
|
|
* Reversed Y axis
|
|
*
|
|
* @type {boolean}
|
|
* @default false
|
|
* @apioption xAxis.reversed
|
|
*/
|
|
// reversed: false,
|
|
/**
|
|
* This option determines how stacks should be ordered within a group.
|
|
* For example reversed xAxis also reverses stacks, so first series
|
|
* comes last in a group. To keep order like for non-reversed xAxis
|
|
* enable this option.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/reversedstacks/
|
|
* Reversed stacks comparison
|
|
* @sample {highstock} highcharts/xaxis/reversedstacks/
|
|
* Reversed stacks comparison
|
|
*
|
|
* @type {boolean}
|
|
* @default false
|
|
* @since 6.1.1
|
|
* @product highcharts highstock
|
|
* @apioption xAxis.reversedStacks
|
|
*/
|
|
/**
|
|
* An optional scrollbar to display on the X axis in response to
|
|
* limiting the minimum and maximum of the axis values.
|
|
*
|
|
* In styled mode, all the presentational options for the scrollbar are
|
|
* replaced by the classes `.highcharts-scrollbar-thumb`,
|
|
* `.highcharts-scrollbar-arrow`, `.highcharts-scrollbar-button`,
|
|
* `.highcharts-scrollbar-rifles` and `.highcharts-scrollbar-track`.
|
|
*
|
|
* @sample {highstock} stock/yaxis/heatmap-scrollbars/
|
|
* Heatmap with both scrollbars
|
|
*
|
|
* @extends scrollbar
|
|
* @since 4.2.6
|
|
* @product highstock
|
|
* @apioption xAxis.scrollbar
|
|
*/
|
|
/**
|
|
* Whether to show the axis line and title when the axis has no data.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/showempty/
|
|
* When clicking the legend to hide series, one axis preserves
|
|
* line and title, the other doesn't
|
|
* @sample {highstock} highcharts/yaxis/showempty/
|
|
* When clicking the legend to hide series, one axis preserves
|
|
* line and title, the other doesn't
|
|
*
|
|
* @since 1.1
|
|
*/
|
|
showEmpty: true,
|
|
/**
|
|
* Whether to show the first tick label.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/showfirstlabel-false/
|
|
* Set to false on X axis
|
|
* @sample {highstock} stock/xaxis/showfirstlabel/
|
|
* Labels below plot lines on Y axis
|
|
*
|
|
* @type {boolean}
|
|
* @default true
|
|
* @apioption xAxis.showFirstLabel
|
|
*/
|
|
/**
|
|
* Whether to show the last tick label. Defaults to `true` on cartesian
|
|
* charts, and `false` on polar charts.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/showlastlabel-true/
|
|
* Set to true on X axis
|
|
* @sample {highstock} stock/xaxis/showfirstlabel/
|
|
* Labels below plot lines on Y axis
|
|
*
|
|
* @type {boolean}
|
|
* @default true
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.showLastLabel
|
|
*/
|
|
/**
|
|
* A soft maximum for the axis. If the series data maximum is less than
|
|
* this, the axis will stay at this maximum, but if the series data
|
|
* maximum is higher, the axis will flex to show all data.
|
|
*
|
|
* @sample highcharts/yaxis/softmin-softmax/
|
|
* Soft min and max
|
|
*
|
|
* @type {number}
|
|
* @since 5.0.1
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.softMax
|
|
*/
|
|
/**
|
|
* A soft minimum for the axis. If the series data minimum is greater
|
|
* than this, the axis will stay at this minimum, but if the series
|
|
* data minimum is lower, the axis will flex to show all data.
|
|
*
|
|
* @sample highcharts/yaxis/softmin-softmax/
|
|
* Soft min and max
|
|
*
|
|
* @type {number}
|
|
* @since 5.0.1
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.softMin
|
|
*/
|
|
/**
|
|
* For datetime axes, this decides where to put the tick between weeks.
|
|
* 0 = Sunday, 1 = Monday.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/startofweek-monday/
|
|
* Monday by default
|
|
* @sample {highcharts} highcharts/xaxis/startofweek-sunday/
|
|
* Sunday
|
|
* @sample {highstock} stock/xaxis/startofweek-1
|
|
* Monday by default
|
|
* @sample {highstock} stock/xaxis/startofweek-0
|
|
* Sunday
|
|
*
|
|
* @product highcharts highstock gantt
|
|
*/
|
|
startOfWeek: 1,
|
|
/**
|
|
* Whether to force the axis to start on a tick. Use this option with
|
|
* the `minPadding` option to control the axis start.
|
|
*
|
|
* @productdesc {highstock}
|
|
* In Highstock, `startOnTick` is always `false` when the navigator
|
|
* is enabled, to prevent jumpy scrolling.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/startontick-false/
|
|
* False by default
|
|
* @sample {highcharts} highcharts/xaxis/startontick-true/
|
|
* True
|
|
*
|
|
* @since 1.2.0
|
|
*/
|
|
startOnTick: false,
|
|
/**
|
|
* The amount of ticks to draw on the axis. This opens up for aligning
|
|
* the ticks of multiple charts or panes within a chart. This option
|
|
* overrides the `tickPixelInterval` option.
|
|
*
|
|
* This option only has an effect on linear axes. Datetime, logarithmic
|
|
* or category axes are not affected.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/tickamount/
|
|
* 8 ticks on Y axis
|
|
* @sample {highstock} highcharts/yaxis/tickamount/
|
|
* 8 ticks on Y axis
|
|
*
|
|
* @type {number}
|
|
* @since 4.1.0
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.tickAmount
|
|
*/
|
|
/**
|
|
* The interval of the tick marks in axis units. When `undefined`, the
|
|
* tick interval is computed to approximately follow the
|
|
* [tickPixelInterval](#xAxis.tickPixelInterval) on linear and datetime
|
|
* axes. On categorized axes, a `undefined` tickInterval will default to
|
|
* 1, one category. Note that datetime axes are based on milliseconds,
|
|
* so for example an interval of one day is expressed as
|
|
* `24 * 3600 * 1000`.
|
|
*
|
|
* On logarithmic axes, the tickInterval is based on powers, so a
|
|
* tickInterval of 1 means one tick on each of 0.1, 1, 10, 100 etc. A
|
|
* tickInterval of 2 means a tick of 0.1, 10, 1000 etc. A tickInterval
|
|
* of 0.2 puts a tick on 0.1, 0.2, 0.4, 0.6, 0.8, 1, 2, 4, 6, 8, 10, 20,
|
|
* 40 etc.
|
|
*
|
|
*
|
|
* If the tickInterval is too dense for labels to be drawn, Highcharts
|
|
* may remove ticks.
|
|
*
|
|
* If the chart has multiple axes, the [alignTicks](#chart.alignTicks)
|
|
* option may interfere with the `tickInterval` setting.
|
|
*
|
|
* @see [tickPixelInterval](#xAxis.tickPixelInterval)
|
|
* @see [tickPositions](#xAxis.tickPositions)
|
|
* @see [tickPositioner](#xAxis.tickPositioner)
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/tickinterval-5/
|
|
* Tick interval of 5 on a linear axis
|
|
* @sample {highstock} stock/xaxis/tickinterval/
|
|
* Tick interval of 0.01 on Y axis
|
|
*
|
|
* @type {number}
|
|
* @apioption xAxis.tickInterval
|
|
*/
|
|
/**
|
|
* The pixel length of the main tick marks.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/ticklength/
|
|
* 20 px tick length on the X axis
|
|
* @sample {highstock} stock/xaxis/ticks/
|
|
* Formatted ticks on X axis
|
|
*/
|
|
tickLength: 10,
|
|
/**
|
|
* If tickInterval is `null` this option sets the approximate pixel
|
|
* interval of the tick marks. Not applicable to categorized axis.
|
|
*
|
|
* The tick interval is also influenced by the [minTickInterval](
|
|
* #xAxis.minTickInterval) option, that, by default prevents ticks from
|
|
* being denser than the data points.
|
|
*
|
|
* @see [tickInterval](#xAxis.tickInterval)
|
|
* @see [tickPositioner](#xAxis.tickPositioner)
|
|
* @see [tickPositions](#xAxis.tickPositions)
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/tickpixelinterval-50/
|
|
* 50 px on X axis
|
|
* @sample {highstock} stock/xaxis/tickpixelinterval/
|
|
* 200 px on X axis
|
|
*/
|
|
tickPixelInterval: 100,
|
|
/**
|
|
* For categorized axes only. If `on` the tick mark is placed in the
|
|
* center of the category, if `between` the tick mark is placed between
|
|
* categories. The default is `between` if the `tickInterval` is 1, else
|
|
* `on`.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/tickmarkplacement-between/
|
|
* "between" by default
|
|
* @sample {highcharts} highcharts/xaxis/tickmarkplacement-on/
|
|
* "on"
|
|
*
|
|
* @product highcharts gantt
|
|
* @validvalue ["on", "between"]
|
|
*/
|
|
tickmarkPlacement: 'between',
|
|
/**
|
|
* The position of the major tick marks relative to the axis line.
|
|
* Can be one of `inside` and `outside`.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/tickposition-outside/
|
|
* "outside" by default
|
|
* @sample {highcharts} highcharts/xaxis/tickposition-inside/
|
|
* "inside"
|
|
* @sample {highstock} stock/xaxis/ticks/
|
|
* Formatted ticks on X axis
|
|
*
|
|
* @validvalue ["inside", "outside"]
|
|
*/
|
|
tickPosition: 'outside',
|
|
/**
|
|
* A callback function returning array defining where the ticks are
|
|
* laid out on the axis. This overrides the default behaviour of
|
|
* [tickPixelInterval](#xAxis.tickPixelInterval) and [tickInterval](
|
|
* #xAxis.tickInterval). The automatic tick positions are accessible
|
|
* through `this.tickPositions` and can be modified by the callback.
|
|
*
|
|
* @see [tickPositions](#xAxis.tickPositions)
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/tickpositions-tickpositioner/
|
|
* Demo of tickPositions and tickPositioner
|
|
* @sample {highstock} highcharts/xaxis/tickpositions-tickpositioner/
|
|
* Demo of tickPositions and tickPositioner
|
|
*
|
|
* @type {Highcharts.AxisTickPositionerCallbackFunction}
|
|
* @apioption xAxis.tickPositioner
|
|
*/
|
|
/**
|
|
* An array defining where the ticks are laid out on the axis. This
|
|
* overrides the default behaviour of [tickPixelInterval](
|
|
* #xAxis.tickPixelInterval) and [tickInterval](#xAxis.tickInterval).
|
|
*
|
|
* @see [tickPositioner](#xAxis.tickPositioner)
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/tickpositions-tickpositioner/
|
|
* Demo of tickPositions and tickPositioner
|
|
* @sample {highstock} highcharts/xaxis/tickpositions-tickpositioner/
|
|
* Demo of tickPositions and tickPositioner
|
|
*
|
|
* @type {Array<number>}
|
|
* @apioption xAxis.tickPositions
|
|
*/
|
|
/**
|
|
* The pixel width of the major tick marks. Defaults to 0 on category
|
|
* axes, otherwise 1.
|
|
*
|
|
* In styled mode, the stroke width is given in the `.highcharts-tick`
|
|
* class, but in order for the element to be generated on category axes,
|
|
* the option must be explicitly set to 1.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/tickwidth/
|
|
* 10 px width
|
|
* @sample {highcharts} highcharts/css/axis-grid/
|
|
* Styled mode
|
|
* @sample {highstock} stock/xaxis/ticks/
|
|
* Formatted ticks on X axis
|
|
* @sample {highstock} highcharts/css/axis-grid/
|
|
* Styled mode
|
|
*
|
|
* @type {undefined|number}
|
|
* @default {highstock} 1
|
|
* @default {highmaps} 0
|
|
* @apioption xAxis.tickWidth
|
|
*/
|
|
/**
|
|
* The axis title, showing next to the axis line.
|
|
*
|
|
* @productdesc {highmaps}
|
|
* In Highmaps, the axis is hidden by default, but adding an axis title
|
|
* is still possible. X axis and Y axis titles will appear at the bottom
|
|
* and left by default.
|
|
*/
|
|
title: {
|
|
/**
|
|
* Deprecated. Set the `text` to `null` to disable the title.
|
|
*
|
|
* @deprecated
|
|
* @type {boolean}
|
|
* @product highcharts
|
|
* @apioption xAxis.title.enabled
|
|
*/
|
|
/**
|
|
* The pixel distance between the axis labels or line and the title.
|
|
* Defaults to 0 for horizontal axes, 10 for vertical
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/title-margin/
|
|
* Y axis title margin of 60
|
|
*
|
|
* @type {number}
|
|
* @apioption xAxis.title.margin
|
|
*/
|
|
/**
|
|
* The distance of the axis title from the axis line. By default,
|
|
* this distance is computed from the offset width of the labels,
|
|
* the labels' distance from the axis and the title's margin.
|
|
* However when the offset option is set, it overrides all this.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/title-offset/
|
|
* Place the axis title on top of the axis
|
|
* @sample {highstock} highcharts/yaxis/title-offset/
|
|
* Place the axis title on top of the Y axis
|
|
*
|
|
* @type {number}
|
|
* @since 2.2.0
|
|
* @apioption xAxis.title.offset
|
|
*/
|
|
/**
|
|
* Whether to reserve space for the title when laying out the axis.
|
|
*
|
|
* @type {boolean}
|
|
* @default true
|
|
* @since 5.0.11
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.title.reserveSpace
|
|
*/
|
|
/**
|
|
* The rotation of the text in degrees. 0 is horizontal, 270 is
|
|
* vertical reading from bottom to top.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/title-offset/
|
|
* Horizontal
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @apioption xAxis.title.rotation
|
|
*/
|
|
/**
|
|
* The actual text of the axis title. It can contain basic HTML tags
|
|
* like `b`, `i` and `span` with style.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/title-text/
|
|
* Custom HTML
|
|
* @sample {highstock} stock/xaxis/title-text/
|
|
* Titles for both axes
|
|
*
|
|
* @type {string|null}
|
|
* @apioption xAxis.title.text
|
|
*/
|
|
/**
|
|
* Alignment of the text, can be `"left"`, `"right"` or `"center"`.
|
|
* Default alignment depends on the
|
|
* [title.align](xAxis.title.align):
|
|
*
|
|
* Horizontal axes:
|
|
* - for `align` = `"low"`, `textAlign` is set to `left`
|
|
* - for `align` = `"middle"`, `textAlign` is set to `center`
|
|
* - for `align` = `"high"`, `textAlign` is set to `right`
|
|
*
|
|
* Vertical axes:
|
|
* - for `align` = `"low"` and `opposite` = `true`, `textAlign` is
|
|
* set to `right`
|
|
* - for `align` = `"low"` and `opposite` = `false`, `textAlign` is
|
|
* set to `left`
|
|
* - for `align` = `"middle"`, `textAlign` is set to `center`
|
|
* - for `align` = `"high"` and `opposite` = `true` `textAlign` is
|
|
* set to `left`
|
|
* - for `align` = `"high"` and `opposite` = `false` `textAlign` is
|
|
* set to `right`
|
|
*
|
|
* @type {Highcharts.AlignValue}
|
|
* @apioption xAxis.title.textAlign
|
|
*/
|
|
/**
|
|
* Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)
|
|
* to render the axis title.
|
|
*
|
|
* @type {boolean}
|
|
* @default false
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.title.useHTML
|
|
*/
|
|
/**
|
|
* Horizontal pixel offset of the title position.
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 4.1.6
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.title.x
|
|
*/
|
|
/**
|
|
* Vertical pixel offset of the title position.
|
|
*
|
|
* @type {number}
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.title.y
|
|
*/
|
|
/**
|
|
* Alignment of the title relative to the axis values. Possible
|
|
* values are "low", "middle" or "high".
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/title-align-low/
|
|
* "low"
|
|
* @sample {highcharts} highcharts/xaxis/title-align-center/
|
|
* "middle" by default
|
|
* @sample {highcharts} highcharts/xaxis/title-align-high/
|
|
* "high"
|
|
* @sample {highcharts} highcharts/yaxis/title-offset/
|
|
* Place the Y axis title on top of the axis
|
|
* @sample {highstock} stock/xaxis/title-align/
|
|
* Aligned to "high" value
|
|
*
|
|
* @type {Highcharts.AxisTitleAlignValue}
|
|
*/
|
|
align: 'middle',
|
|
/**
|
|
* CSS styles for the title. If the title text is longer than the
|
|
* axis length, it will wrap to multiple lines by default. This can
|
|
* be customized by setting `textOverflow: 'ellipsis'`, by
|
|
* setting a specific `width` or by setting `whiteSpace: 'nowrap'`.
|
|
*
|
|
* In styled mode, the stroke width is given in the
|
|
* `.highcharts-axis-title` class.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/title-style/
|
|
* Red
|
|
* @sample {highcharts} highcharts/css/axis/
|
|
* Styled mode
|
|
*
|
|
* @type {Highcharts.CSSObject}
|
|
*/
|
|
style: {
|
|
/** @internal */
|
|
color: '#666666'
|
|
}
|
|
},
|
|
/**
|
|
* The type of axis. Can be one of `linear`, `logarithmic`, `datetime`
|
|
* or `category`. In a datetime axis, the numbers are given in
|
|
* milliseconds, and tick marks are placed on appropriate values like
|
|
* full hours or days. In a category axis, the
|
|
* [point names](#series.line.data.name) of the chart's series are used
|
|
* for categories, if not a [categories](#xAxis.categories) array is
|
|
* defined.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/type-linear/
|
|
* Linear
|
|
* @sample {highcharts} highcharts/yaxis/type-log/
|
|
* Logarithmic
|
|
* @sample {highcharts} highcharts/yaxis/type-log-minorgrid/
|
|
* Logarithmic with minor grid lines
|
|
* @sample {highcharts} highcharts/xaxis/type-log-both/
|
|
* Logarithmic on two axes
|
|
* @sample {highcharts} highcharts/yaxis/type-log-negative/
|
|
* Logarithmic with extension to emulate negative values
|
|
*
|
|
* @type {Highcharts.AxisTypeValue}
|
|
* @product highcharts gantt
|
|
*/
|
|
type: 'linear',
|
|
/**
|
|
* If there are multiple axes on the same side of the chart, the pixel
|
|
* margin between the axes. Defaults to 0 on vertical axes, 15 on
|
|
* horizontal axes.
|
|
*
|
|
* @type {number}
|
|
* @since 7.0.3
|
|
* @apioption xAxis.margin
|
|
*/
|
|
/**
|
|
* Applies only when the axis `type` is `category`. When `uniqueNames`
|
|
* is true, points are placed on the X axis according to their names.
|
|
* If the same point name is repeated in the same or another series,
|
|
* the point is placed on the same X position as other points of the
|
|
* same name. When `uniqueNames` is false, the points are laid out in
|
|
* increasing X positions regardless of their names, and the X axis
|
|
* category will take the name of the last point in each position.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/uniquenames-true/
|
|
* True by default
|
|
* @sample {highcharts} highcharts/xaxis/uniquenames-false/
|
|
* False
|
|
*
|
|
* @type {boolean}
|
|
* @default true
|
|
* @since 4.2.7
|
|
* @product highcharts gantt
|
|
* @apioption xAxis.uniqueNames
|
|
*/
|
|
/**
|
|
* Datetime axis only. An array determining what time intervals the
|
|
* ticks are allowed to fall on. Each array item is an array where the
|
|
* first value is the time unit and the second value another array of
|
|
* allowed multiples.
|
|
*
|
|
* Defaults to:
|
|
* ```js
|
|
* units: [[
|
|
* 'millisecond', // unit name
|
|
* [1, 2, 5, 10, 20, 25, 50, 100, 200, 500] // allowed multiples
|
|
* ], [
|
|
* 'second',
|
|
* [1, 2, 5, 10, 15, 30]
|
|
* ], [
|
|
* 'minute',
|
|
* [1, 2, 5, 10, 15, 30]
|
|
* ], [
|
|
* 'hour',
|
|
* [1, 2, 3, 4, 6, 8, 12]
|
|
* ], [
|
|
* 'day',
|
|
* [1]
|
|
* ], [
|
|
* 'week',
|
|
* [1]
|
|
* ], [
|
|
* 'month',
|
|
* [1, 3, 6]
|
|
* ], [
|
|
* 'year',
|
|
* null
|
|
* ]]
|
|
* ```
|
|
*
|
|
* @type {Array<Array<string,(Array<number>|null)>>}
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.units
|
|
*/
|
|
/**
|
|
* Whether axis, including axis title, line, ticks and labels, should
|
|
* be visible.
|
|
*
|
|
* @type {boolean}
|
|
* @default true
|
|
* @since 4.1.9
|
|
* @product highcharts highstock gantt
|
|
* @apioption xAxis.visible
|
|
*/
|
|
/**
|
|
* Color of the minor, secondary grid lines.
|
|
*
|
|
* In styled mode, the stroke width is given in the
|
|
* `.highcharts-minor-grid-line` class.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/minorgridlinecolor/
|
|
* Bright grey lines from Y axis
|
|
* @sample {highcharts|highstock} highcharts/css/axis-grid/
|
|
* Styled mode
|
|
* @sample {highstock} stock/xaxis/minorgridlinecolor/
|
|
* Bright grey lines from Y axis
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @default #f2f2f2
|
|
*/
|
|
minorGridLineColor: '#f2f2f2',
|
|
/**
|
|
* Width of the minor, secondary grid lines.
|
|
*
|
|
* In styled mode, the stroke width is given in the
|
|
* `.highcharts-grid-line` class.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/minorgridlinewidth/
|
|
* 2px lines from Y axis
|
|
* @sample {highcharts|highstock} highcharts/css/axis-grid/
|
|
* Styled mode
|
|
* @sample {highstock} stock/xaxis/minorgridlinewidth/
|
|
* 2px lines from Y axis
|
|
*/
|
|
minorGridLineWidth: 1,
|
|
/**
|
|
* Color for the minor tick marks.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/minortickcolor/
|
|
* Black tick marks on Y axis
|
|
* @sample {highstock} stock/xaxis/minorticks/
|
|
* Black tick marks on Y axis
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @default #999999
|
|
*/
|
|
minorTickColor: '#999999',
|
|
/**
|
|
* The color of the line marking the axis itself.
|
|
*
|
|
* In styled mode, the line stroke is given in the
|
|
* `.highcharts-axis-line` or `.highcharts-xaxis-line` class.
|
|
*
|
|
* @productdesc {highmaps}
|
|
* In Highmaps, the axis line is hidden by default, because the axis is
|
|
* not visible by default.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/linecolor/
|
|
* A red line on Y axis
|
|
* @sample {highcharts|highstock} highcharts/css/axis/
|
|
* Axes in styled mode
|
|
* @sample {highstock} stock/xaxis/linecolor/
|
|
* A red line on X axis
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @default #ccd6eb
|
|
*/
|
|
lineColor: '#ccd6eb',
|
|
/**
|
|
* The width of the line marking the axis itself.
|
|
*
|
|
* In styled mode, the stroke width is given in the
|
|
* `.highcharts-axis-line` or `.highcharts-xaxis-line` class.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/linecolor/
|
|
* A 1px line on Y axis
|
|
* @sample {highcharts|highstock} highcharts/css/axis/
|
|
* Axes in styled mode
|
|
* @sample {highstock} stock/xaxis/linewidth/
|
|
* A 2px line on X axis
|
|
*
|
|
* @default {highcharts|highstock} 1
|
|
* @default {highmaps} 0
|
|
*/
|
|
lineWidth: 1,
|
|
/**
|
|
* Color of the grid lines extending the ticks across the plot area.
|
|
*
|
|
* In styled mode, the stroke is given in the `.highcharts-grid-line`
|
|
* class.
|
|
*
|
|
* @productdesc {highmaps}
|
|
* In Highmaps, the grid lines are hidden by default.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/gridlinecolor/
|
|
* Green lines
|
|
* @sample {highcharts|highstock} highcharts/css/axis-grid/
|
|
* Styled mode
|
|
* @sample {highstock} stock/xaxis/gridlinecolor/
|
|
* Green lines
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @default #e6e6e6
|
|
*/
|
|
gridLineColor: '#e6e6e6',
|
|
// gridLineDashStyle: 'solid',
|
|
/**
|
|
* The width of the grid lines extending the ticks across the plot area.
|
|
*
|
|
* In styled mode, the stroke width is given in the
|
|
* `.highcharts-grid-line` class.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/gridlinewidth/
|
|
* 2px lines
|
|
* @sample {highcharts|highstock} highcharts/css/axis-grid/
|
|
* Styled mode
|
|
* @sample {highstock} stock/xaxis/gridlinewidth/
|
|
* 2px lines
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @apioption xAxis.gridLineWidth
|
|
*/
|
|
// gridLineWidth: 0,
|
|
/**
|
|
* The height as the vertical axis. If it's a number, it is
|
|
* interpreted as pixels.
|
|
*
|
|
* Since Highcharts 2: If it's a percentage string, it is interpreted
|
|
* as percentages of the total plot height.
|
|
*
|
|
* @type {number|string}
|
|
* @product highcharts highstock
|
|
* @apioption xAxis.height
|
|
*/
|
|
/**
|
|
* The width as the horizontal axis. If it's a number, it is interpreted
|
|
* as pixels.
|
|
*
|
|
* Since Highcharts v5.0.13: If it's a percentage string, it is
|
|
* interpreted as percentages of the total plot width.
|
|
*
|
|
* @type {number|string}
|
|
* @product highcharts highstock
|
|
* @apioption xAxis.width
|
|
*/
|
|
/**
|
|
* Color for the main tick marks.
|
|
*
|
|
* In styled mode, the stroke is given in the `.highcharts-tick`
|
|
* class.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/tickcolor/
|
|
* Red ticks on X axis
|
|
* @sample {highcharts|highstock} highcharts/css/axis-grid/
|
|
* Styled mode
|
|
* @sample {highstock} stock/xaxis/ticks/
|
|
* Formatted ticks on X axis
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @default #ccd6eb
|
|
*/
|
|
tickColor: '#ccd6eb'
|
|
// tickWidth: 1
|
|
};
|
|
/**
|
|
* The Y axis or value axis. Normally this is the vertical axis,
|
|
* though if the chart is inverted this is the horizontal axis.
|
|
* In case of multiple axes, the yAxis node is an array of
|
|
* configuration objects.
|
|
*
|
|
* See [the Axis object](/class-reference/Highcharts.Axis) for programmatic
|
|
* access to the axis.
|
|
*
|
|
* @type {*|Array<*>}
|
|
* @extends xAxis
|
|
* @excluding currentDateIndicator,ordinal,overscroll
|
|
* @optionparent yAxis
|
|
*
|
|
* @private
|
|
*/
|
|
Axis.defaultYAxisOptions = {
|
|
/**
|
|
* The type of axis. Can be one of `linear`, `logarithmic`, `datetime`,
|
|
* `category` or `treegrid`. Defaults to `treegrid` for Gantt charts,
|
|
* `linear` for other chart types.
|
|
*
|
|
* In a datetime axis, the numbers are given in milliseconds, and tick
|
|
* marks are placed on appropriate values, like full hours or days. In a
|
|
* category or treegrid axis, the [point names](#series.line.data.name)
|
|
* of the chart's series are used for categories, if a
|
|
* [categories](#xAxis.categories) array is not defined.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/type-log-minorgrid/
|
|
* Logarithmic with minor grid lines
|
|
* @sample {highcharts} highcharts/yaxis/type-log-negative/
|
|
* Logarithmic with extension to emulate negative values
|
|
* @sample {gantt} gantt/treegrid-axis/demo
|
|
* Treegrid axis
|
|
*
|
|
* @type {Highcharts.AxisTypeValue}
|
|
* @default {highcharts} linear
|
|
* @default {gantt} treegrid
|
|
* @product highcharts gantt
|
|
* @apioption yAxis.type
|
|
*/
|
|
/**
|
|
* The height of the Y axis. If it's a number, it is interpreted as
|
|
* pixels.
|
|
*
|
|
* Since Highcharts 2: If it's a percentage string, it is interpreted as
|
|
* percentages of the total plot height.
|
|
*
|
|
* @see [yAxis.top](#yAxis.top)
|
|
*
|
|
* @sample {highstock} stock/demo/candlestick-and-volume/
|
|
* Percentage height panes
|
|
*
|
|
* @type {number|string}
|
|
* @product highcharts highstock
|
|
* @apioption yAxis.height
|
|
*/
|
|
/**
|
|
* Solid gauge only. Unless [stops](#yAxis.stops) are set, the color
|
|
* to represent the maximum value of the Y axis.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/mincolor-maxcolor/
|
|
* Min and max colors
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @default #003399
|
|
* @since 4.0
|
|
* @product highcharts
|
|
* @apioption yAxis.maxColor
|
|
*/
|
|
/**
|
|
* Solid gauge only. Unless [stops](#yAxis.stops) are set, the color
|
|
* to represent the minimum value of the Y axis.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/mincolor-maxcolor/
|
|
* Min and max color
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @default #e6ebf5
|
|
* @since 4.0
|
|
* @product highcharts
|
|
* @apioption yAxis.minColor
|
|
*/
|
|
/**
|
|
* Whether to reverse the axis so that the highest number is closest
|
|
* to the origin.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/reversed/
|
|
* Reversed Y axis
|
|
* @sample {highstock} stock/xaxis/reversed/
|
|
* Reversed Y axis
|
|
*
|
|
* @type {boolean}
|
|
* @default {highcharts} false
|
|
* @default {highstock} false
|
|
* @default {highmaps} true
|
|
* @default {gantt} true
|
|
* @apioption yAxis.reversed
|
|
*/
|
|
/**
|
|
* If `true`, the first series in a stack will be drawn on top in a
|
|
* positive, non-reversed Y axis. If `false`, the first series is in
|
|
* the base of the stack.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/reversedstacks-false/
|
|
* Non-reversed stacks
|
|
* @sample {highstock} highcharts/yaxis/reversedstacks-false/
|
|
* Non-reversed stacks
|
|
*
|
|
* @type {boolean}
|
|
* @default true
|
|
* @since 3.0.10
|
|
* @product highcharts highstock
|
|
* @apioption yAxis.reversedStacks
|
|
*/
|
|
/**
|
|
* Solid gauge series only. Color stops for the solid gauge. Use this
|
|
* in cases where a linear gradient between a `minColor` and `maxColor`
|
|
* is not sufficient. The stops is an array of tuples, where the first
|
|
* item is a float between 0 and 1 assigning the relative position in
|
|
* the gradient, and the second item is the color.
|
|
*
|
|
* For solid gauges, the Y axis also inherits the concept of
|
|
* [data classes](https://api.highcharts.com/highmaps#colorAxis.dataClasses)
|
|
* from the Highmaps color axis.
|
|
*
|
|
* @see [minColor](#yAxis.minColor)
|
|
* @see [maxColor](#yAxis.maxColor)
|
|
*
|
|
* @sample {highcharts} highcharts/demo/gauge-solid/
|
|
* True by default
|
|
*
|
|
* @type {Array<Highcharts.GradientColorStopObject>}
|
|
* @since 4.0
|
|
* @product highcharts
|
|
* @apioption yAxis.stops
|
|
*/
|
|
/**
|
|
* The pixel width of the major tick marks.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/tickwidth/ 10 px width
|
|
* @sample {highstock} stock/xaxis/ticks/ Formatted ticks on X axis
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @product highcharts highstock gantt
|
|
* @apioption yAxis.tickWidth
|
|
*/
|
|
/**
|
|
* Angular gauges and solid gauges only.
|
|
* The label's pixel distance from the perimeter of the plot area.
|
|
*
|
|
* Since v7.1.2: If it's a percentage string, it is interpreted the
|
|
* same as [series.radius](#plotOptions.gauge.radius), so label can be
|
|
* aligned under the gauge's shape.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/labels-distance/
|
|
* Labels centered under the arc
|
|
*
|
|
* @type {number|string}
|
|
* @default -25
|
|
* @product highcharts
|
|
* @apioption yAxis.labels.distance
|
|
*/
|
|
/**
|
|
* The y position offset of the label relative to the tick position
|
|
* on the axis.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-x/
|
|
* Y axis labels placed on grid lines
|
|
*
|
|
* @type {number}
|
|
* @default {highcharts} 3
|
|
* @default {highstock} -2
|
|
* @default {highmaps} 3
|
|
* @apioption yAxis.labels.y
|
|
*/
|
|
/**
|
|
* Whether to force the axis to end on a tick. Use this option with
|
|
* the `maxPadding` option to control the axis end.
|
|
*
|
|
* This option is always disabled, when panning type is
|
|
* either `y` or `xy`.
|
|
*
|
|
* @see [type](#chart.panning.type)
|
|
*
|
|
*
|
|
* @sample {highcharts} highcharts/chart/reflow-true/
|
|
* True by default
|
|
* @sample {highcharts} highcharts/yaxis/endontick/
|
|
* False
|
|
* @sample {highstock} stock/demo/basic-line/
|
|
* True by default
|
|
* @sample {highstock} stock/xaxis/endontick/
|
|
* False for Y axis
|
|
*
|
|
* @since 1.2.0
|
|
*/
|
|
endOnTick: true,
|
|
/**
|
|
* Padding of the max value relative to the length of the axis. A
|
|
* padding of 0.05 will make a 100px axis 5px longer. This is useful
|
|
* when you don't want the highest data value to appear on the edge
|
|
* of the plot area. When the axis' `max` option is set or a max extreme
|
|
* is set using `axis.setExtremes()`, the maxPadding will be ignored.
|
|
*
|
|
* Also the `softThreshold` option takes precedence over `maxPadding`,
|
|
* so if the data is tangent to the threshold, `maxPadding` may not
|
|
* apply unless `softThreshold` is set to false.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/maxpadding-02/
|
|
* Max padding of 0.2
|
|
* @sample {highstock} stock/xaxis/minpadding-maxpadding/
|
|
* Greater min- and maxPadding
|
|
*
|
|
* @since 1.2.0
|
|
* @product highcharts highstock gantt
|
|
*/
|
|
maxPadding: 0.05,
|
|
/**
|
|
* Padding of the min value relative to the length of the axis. A
|
|
* padding of 0.05 will make a 100px axis 5px longer. This is useful
|
|
* when you don't want the lowest data value to appear on the edge
|
|
* of the plot area. When the axis' `min` option is set or a max extreme
|
|
* is set using `axis.setExtremes()`, the maxPadding will be ignored.
|
|
*
|
|
* Also the `softThreshold` option takes precedence over `minPadding`,
|
|
* so if the data is tangent to the threshold, `minPadding` may not
|
|
* apply unless `softThreshold` is set to false.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/minpadding/
|
|
* Min padding of 0.2
|
|
* @sample {highstock} stock/xaxis/minpadding-maxpadding/
|
|
* Greater min- and maxPadding
|
|
*
|
|
* @since 1.2.0
|
|
* @product highcharts highstock gantt
|
|
*/
|
|
minPadding: 0.05,
|
|
/**
|
|
* @productdesc {highstock}
|
|
* In Highstock 1.x, the Y axis was placed on the left side by default.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/opposite/
|
|
* Secondary Y axis opposite
|
|
* @sample {highstock} stock/xaxis/opposite/
|
|
* Y axis on left side
|
|
*
|
|
* @type {boolean}
|
|
* @default {highstock} true
|
|
* @default {highcharts} false
|
|
* @product highstock highcharts gantt
|
|
* @apioption yAxis.opposite
|
|
*/
|
|
/**
|
|
* @see [tickInterval](#xAxis.tickInterval)
|
|
* @see [tickPositioner](#xAxis.tickPositioner)
|
|
* @see [tickPositions](#xAxis.tickPositions)
|
|
*/
|
|
tickPixelInterval: 72,
|
|
showLastLabel: true,
|
|
/**
|
|
* @extends xAxis.labels
|
|
*/
|
|
labels: {
|
|
/**
|
|
* What part of the string the given position is anchored to. Can
|
|
* be one of `"left"`, `"center"` or `"right"`. The exact position
|
|
* also depends on the `labels.x` setting.
|
|
*
|
|
* Angular gauges and solid gauges defaults to `"center"`.
|
|
* Solid gauges with two labels have additional option `"auto"`
|
|
* for automatic horizontal and vertical alignment.
|
|
*
|
|
* @see [yAxis.labels.distance](#yAxis.labels.distance)
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/labels-align-left/
|
|
* Left
|
|
* @sample {highcharts} highcharts/series-solidgauge/labels-auto-aligned/
|
|
* Solid gauge labels auto aligned
|
|
*
|
|
* @type {Highcharts.AlignValue}
|
|
* @default {highcharts|highmaps} right
|
|
* @default {highstock} left
|
|
* @apioption yAxis.labels.align
|
|
*/
|
|
/**
|
|
* The x position offset of the label relative to the tick position
|
|
* on the axis. Defaults to -15 for left axis, 15 for right axis.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/labels-x/
|
|
* Y axis labels placed on grid lines
|
|
*/
|
|
x: -8
|
|
},
|
|
/**
|
|
* @productdesc {highmaps}
|
|
* In Highmaps, the axis line is hidden by default, because the axis is
|
|
* not visible by default.
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @apioption yAxis.lineColor
|
|
*/
|
|
/**
|
|
* @sample {highcharts} highcharts/yaxis/max-200/
|
|
* Y axis max of 200
|
|
* @sample {highcharts} highcharts/yaxis/max-logarithmic/
|
|
* Y axis max on logarithmic axis
|
|
* @sample {highstock} stock/yaxis/min-max/
|
|
* Fixed min and max on Y axis
|
|
* @sample {highmaps} maps/axis/min-max/
|
|
* Pre-zoomed to a specific area
|
|
*
|
|
* @apioption yAxis.max
|
|
*/
|
|
/**
|
|
* @sample {highcharts} highcharts/yaxis/min-startontick-false/
|
|
* -50 with startOnTick to false
|
|
* @sample {highcharts} highcharts/yaxis/min-startontick-true/
|
|
* -50 with startOnTick true by default
|
|
* @sample {highstock} stock/yaxis/min-max/
|
|
* Fixed min and max on Y axis
|
|
* @sample {highmaps} maps/axis/min-max/
|
|
* Pre-zoomed to a specific area
|
|
*
|
|
* @apioption yAxis.min
|
|
*/
|
|
/**
|
|
* An optional scrollbar to display on the Y axis in response to
|
|
* limiting the minimum an maximum of the axis values.
|
|
*
|
|
* In styled mode, all the presentational options for the scrollbar
|
|
* are replaced by the classes `.highcharts-scrollbar-thumb`,
|
|
* `.highcharts-scrollbar-arrow`, `.highcharts-scrollbar-button`,
|
|
* `.highcharts-scrollbar-rifles` and `.highcharts-scrollbar-track`.
|
|
*
|
|
* @sample {highstock} stock/yaxis/scrollbar/
|
|
* Scrollbar on the Y axis
|
|
*
|
|
* @extends scrollbar
|
|
* @since 4.2.6
|
|
* @product highstock
|
|
* @excluding height
|
|
* @apioption yAxis.scrollbar
|
|
*/
|
|
/**
|
|
* Enable the scrollbar on the Y axis.
|
|
*
|
|
* @sample {highstock} stock/yaxis/scrollbar/
|
|
* Enabled on Y axis
|
|
*
|
|
* @type {boolean}
|
|
* @default false
|
|
* @since 4.2.6
|
|
* @product highstock
|
|
* @apioption yAxis.scrollbar.enabled
|
|
*/
|
|
/**
|
|
* Pixel margin between the scrollbar and the axis elements.
|
|
*
|
|
* @type {number}
|
|
* @default 10
|
|
* @since 4.2.6
|
|
* @product highstock
|
|
* @apioption yAxis.scrollbar.margin
|
|
*/
|
|
/**
|
|
* Whether to show the scrollbar when it is fully zoomed out at max
|
|
* range. Setting it to `false` on the Y axis makes the scrollbar stay
|
|
* hidden until the user zooms in, like common in browsers.
|
|
*
|
|
* @type {boolean}
|
|
* @default true
|
|
* @since 4.2.6
|
|
* @product highstock
|
|
* @apioption yAxis.scrollbar.showFull
|
|
*/
|
|
/**
|
|
* The width of a vertical scrollbar or height of a horizontal
|
|
* scrollbar. Defaults to 20 on touch devices.
|
|
*
|
|
* @type {number}
|
|
* @default 14
|
|
* @since 4.2.6
|
|
* @product highstock
|
|
* @apioption yAxis.scrollbar.size
|
|
*/
|
|
/**
|
|
* Z index of the scrollbar elements.
|
|
*
|
|
* @type {number}
|
|
* @default 3
|
|
* @since 4.2.6
|
|
* @product highstock
|
|
* @apioption yAxis.scrollbar.zIndex
|
|
*/
|
|
/**
|
|
* A soft maximum for the axis. If the series data maximum is less
|
|
* than this, the axis will stay at this maximum, but if the series
|
|
* data maximum is higher, the axis will flex to show all data.
|
|
*
|
|
* **Note**: The [series.softThreshold](
|
|
* #plotOptions.series.softThreshold) option takes precedence over this
|
|
* option.
|
|
*
|
|
* @sample highcharts/yaxis/softmin-softmax/
|
|
* Soft min and max
|
|
*
|
|
* @type {number}
|
|
* @since 5.0.1
|
|
* @product highcharts highstock gantt
|
|
* @apioption yAxis.softMax
|
|
*/
|
|
/**
|
|
* A soft minimum for the axis. If the series data minimum is greater
|
|
* than this, the axis will stay at this minimum, but if the series
|
|
* data minimum is lower, the axis will flex to show all data.
|
|
*
|
|
* **Note**: The [series.softThreshold](
|
|
* #plotOptions.series.softThreshold) option takes precedence over this
|
|
* option.
|
|
*
|
|
* @sample highcharts/yaxis/softmin-softmax/
|
|
* Soft min and max
|
|
*
|
|
* @type {number}
|
|
* @since 5.0.1
|
|
* @product highcharts highstock gantt
|
|
* @apioption yAxis.softMin
|
|
*/
|
|
/**
|
|
* Defines the horizontal alignment of the stack total label. Can be one
|
|
* of `"left"`, `"center"` or `"right"`. The default value is calculated
|
|
* at runtime and depends on orientation and whether the stack is
|
|
* positive or negative.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-align-left/
|
|
* Aligned to the left
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-align-center/
|
|
* Aligned in center
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-align-right/
|
|
* Aligned to the right
|
|
*
|
|
* @type {Highcharts.AlignValue}
|
|
* @since 2.1.5
|
|
* @product highcharts
|
|
* @apioption yAxis.stackLabels.align
|
|
*/
|
|
/**
|
|
* A format string for the data label. Available variables are the same
|
|
* as for `formatter`.
|
|
*
|
|
* @type {string}
|
|
* @default {total}
|
|
* @since 3.0.2
|
|
* @product highcharts highstock
|
|
* @apioption yAxis.stackLabels.format
|
|
*/
|
|
/**
|
|
* Rotation of the labels in degrees.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-rotation/
|
|
* Labels rotated 45°
|
|
*
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 2.1.5
|
|
* @product highcharts
|
|
* @apioption yAxis.stackLabels.rotation
|
|
*/
|
|
/**
|
|
* The text alignment for the label. While `align` determines where the
|
|
* texts anchor point is placed with regards to the stack, `textAlign`
|
|
* determines how the text is aligned against its anchor point. Possible
|
|
* values are `"left"`, `"center"` and `"right"`. The default value is
|
|
* calculated at runtime and depends on orientation and whether the
|
|
* stack is positive or negative.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-textalign-left/
|
|
* Label in center position but text-aligned left
|
|
*
|
|
* @type {Highcharts.AlignValue}
|
|
* @since 2.1.5
|
|
* @product highcharts
|
|
* @apioption yAxis.stackLabels.textAlign
|
|
*/
|
|
/**
|
|
* Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)
|
|
* to render the labels.
|
|
*
|
|
* @type {boolean}
|
|
* @default false
|
|
* @since 3.0
|
|
* @product highcharts highstock
|
|
* @apioption yAxis.stackLabels.useHTML
|
|
*/
|
|
/**
|
|
* Defines the vertical alignment of the stack total label. Can be one
|
|
* of `"top"`, `"middle"` or `"bottom"`. The default value is calculated
|
|
* at runtime and depends on orientation and whether the stack is
|
|
* positive or negative.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-verticalalign-top/
|
|
* Vertically aligned top
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-verticalalign-middle/
|
|
* Vertically aligned middle
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-verticalalign-bottom/
|
|
* Vertically aligned bottom
|
|
*
|
|
* @type {Highcharts.VerticalAlignValue}
|
|
* @since 2.1.5
|
|
* @product highcharts
|
|
* @apioption yAxis.stackLabels.verticalAlign
|
|
*/
|
|
/**
|
|
* The x position offset of the label relative to the left of the
|
|
* stacked bar. The default value is calculated at runtime and depends
|
|
* on orientation and whether the stack is positive or negative.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-x/
|
|
* Stack total labels with x offset
|
|
*
|
|
* @type {number}
|
|
* @since 2.1.5
|
|
* @product highcharts
|
|
* @apioption yAxis.stackLabels.x
|
|
*/
|
|
/**
|
|
* The y position offset of the label relative to the tick position
|
|
* on the axis. The default value is calculated at runtime and depends
|
|
* on orientation and whether the stack is positive or negative.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-y/
|
|
* Stack total labels with y offset
|
|
*
|
|
* @type {number}
|
|
* @since 2.1.5
|
|
* @product highcharts
|
|
* @apioption yAxis.stackLabels.y
|
|
*/
|
|
/**
|
|
* Whether to force the axis to start on a tick. Use this option with
|
|
* the `maxPadding` option to control the axis start.
|
|
*
|
|
* This option is always disabled, when panning type is
|
|
* either `y` or `xy`.
|
|
*
|
|
* @see [type](#chart.panning.type)
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/startontick-false/
|
|
* False by default
|
|
* @sample {highcharts} highcharts/xaxis/startontick-true/
|
|
* True
|
|
* @sample {highstock} stock/xaxis/endontick/
|
|
* False for Y axis
|
|
*
|
|
* @since 1.2.0
|
|
* @product highcharts highstock gantt
|
|
*/
|
|
startOnTick: true,
|
|
title: {
|
|
/**
|
|
* The pixel distance between the axis labels and the title.
|
|
* Positive values are outside the axis line, negative are inside.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/title-margin/
|
|
* Y axis title margin of 60
|
|
*
|
|
* @type {number}
|
|
* @default 40
|
|
* @apioption yAxis.title.margin
|
|
*/
|
|
/**
|
|
* The rotation of the text in degrees. 0 is horizontal, 270 is
|
|
* vertical reading from bottom to top.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/title-offset/
|
|
* Horizontal
|
|
*/
|
|
rotation: 270,
|
|
/**
|
|
* The actual text of the axis title. Horizontal texts can contain
|
|
* HTML, but rotated texts are painted using vector techniques and
|
|
* must be clean text. The Y axis title is disabled by setting the
|
|
* `text` option to `undefined`.
|
|
*
|
|
* @sample {highcharts} highcharts/xaxis/title-text/
|
|
* Custom HTML
|
|
*
|
|
* @type {string|null}
|
|
* @default {highcharts} Values
|
|
* @default {highstock} undefined
|
|
* @product highcharts highstock gantt
|
|
*/
|
|
text: 'Values'
|
|
},
|
|
/**
|
|
* The top position of the Y axis. If it's a number, it is interpreted
|
|
* as pixel position relative to the chart.
|
|
*
|
|
* Since Highcharts 2: If it's a percentage string, it is interpreted as
|
|
* percentages of the plot height, offset from plot area top.
|
|
*
|
|
* @see [yAxis.height](#yAxis.height)
|
|
*
|
|
* @sample {highstock} stock/demo/candlestick-and-volume/
|
|
* Percentage height panes
|
|
*
|
|
* @type {number|string}
|
|
* @product highcharts highstock
|
|
* @apioption yAxis.top
|
|
*/
|
|
/**
|
|
* The stack labels show the total value for each bar in a stacked
|
|
* column or bar chart. The label will be placed on top of positive
|
|
* columns and below negative columns. In case of an inverted column
|
|
* chart or a bar chart the label is placed to the right of positive
|
|
* bars and to the left of negative bars.
|
|
*
|
|
* @product highcharts
|
|
*/
|
|
stackLabels: {
|
|
/**
|
|
* Allow the stack labels to overlap.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-allowoverlap-false/
|
|
* Default false
|
|
*
|
|
* @since 5.0.13
|
|
* @product highcharts
|
|
*/
|
|
allowOverlap: false,
|
|
/**
|
|
* The background color or gradient for the stack label.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-box/
|
|
* Stack labels box options
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @since 8.1.0
|
|
* @apioption yAxis.stackLabels.backgroundColor
|
|
*/
|
|
/**
|
|
* The border color for the stack label. Defaults to `undefined`.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-box/
|
|
* Stack labels box options
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @since 8.1.0
|
|
* @apioption yAxis.stackLabels.borderColor
|
|
*/
|
|
/**
|
|
* The border radius in pixels for the stack label.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-box/
|
|
* Stack labels box options
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 8.1.0
|
|
* @apioption yAxis.stackLabels.borderRadius
|
|
*/
|
|
/**
|
|
* The border width in pixels for the stack label.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-box/
|
|
* Stack labels box options
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 8.1.0
|
|
* @apioption yAxis.stackLabels.borderWidth
|
|
*/
|
|
/**
|
|
* Enable or disable the stack total labels.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-enabled/
|
|
* Enabled stack total labels
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-enabled-waterfall/
|
|
* Enabled stack labels in waterfall chart
|
|
*
|
|
* @since 2.1.5
|
|
* @product highcharts
|
|
*/
|
|
enabled: false,
|
|
/**
|
|
* Whether to hide stack labels that are outside the plot area.
|
|
* By default, the stack label is moved
|
|
* inside the plot area according to the
|
|
* [overflow](/highcharts/#yAxis/stackLabels/overflow)
|
|
* option.
|
|
*
|
|
* @type {boolean}
|
|
* @since 7.1.3
|
|
*/
|
|
crop: true,
|
|
/**
|
|
* How to handle stack total labels that flow outside the plot area.
|
|
* The default is set to `"justify"`,
|
|
* which aligns them inside the plot area.
|
|
* For columns and bars, this means it will be moved inside the bar.
|
|
* To display stack labels outside the plot area,
|
|
* set `crop` to `false` and `overflow` to `"allow"`.
|
|
*
|
|
* @sample highcharts/yaxis/stacklabels-overflow/
|
|
* Stack labels flows outside the plot area.
|
|
*
|
|
* @type {Highcharts.DataLabelsOverflowValue}
|
|
* @since 7.1.3
|
|
*/
|
|
overflow: 'justify',
|
|
/* eslint-disable valid-jsdoc */
|
|
/**
|
|
* Callback JavaScript function to format the label. The value is
|
|
* given by `this.total`.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-formatter/
|
|
* Added units to stack total value
|
|
*
|
|
* @type {Highcharts.FormatterCallbackFunction<Highcharts.StackItemObject>}
|
|
* @since 2.1.5
|
|
* @product highcharts
|
|
*/
|
|
formatter: function () {
|
|
var numberFormatter = this.axis.chart.numberFormatter;
|
|
/* eslint-enable valid-jsdoc */
|
|
return numberFormatter(this.total, -1);
|
|
},
|
|
/**
|
|
* CSS styles for the label.
|
|
*
|
|
* In styled mode, the styles are set in the
|
|
* `.highcharts-stack-label` class.
|
|
*
|
|
* @sample {highcharts} highcharts/yaxis/stacklabels-style/
|
|
* Red stack total labels
|
|
*
|
|
* @type {Highcharts.CSSObject}
|
|
* @since 2.1.5
|
|
* @product highcharts
|
|
*/
|
|
style: {
|
|
/** @internal */
|
|
color: '#000000',
|
|
/** @internal */
|
|
fontSize: '11px',
|
|
/** @internal */
|
|
fontWeight: 'bold',
|
|
/** @internal */
|
|
textOutline: '1px contrast'
|
|
}
|
|
},
|
|
gridLineWidth: 1,
|
|
lineWidth: 0
|
|
// tickWidth: 0
|
|
};
|
|
/**
|
|
* The Z axis or depth axis for 3D plots.
|
|
*
|
|
* See the [Axis class](/class-reference/Highcharts.Axis) for programmatic
|
|
* access to the axis.
|
|
*
|
|
* @sample {highcharts} highcharts/3d/scatter-zaxis-categories/
|
|
* Z-Axis with Categories
|
|
* @sample {highcharts} highcharts/3d/scatter-zaxis-grid/
|
|
* Z-Axis with styling
|
|
*
|
|
* @type {*|Array<*>}
|
|
* @extends xAxis
|
|
* @since 5.0.0
|
|
* @product highcharts
|
|
* @excluding breaks, crosshair, height, left, lineColor, lineWidth,
|
|
* nameToX, showEmpty, top, width
|
|
* @apioption zAxis
|
|
*
|
|
* @private
|
|
*/
|
|
// This variable extends the defaultOptions for left axes.
|
|
Axis.defaultLeftAxisOptions = {
|
|
labels: {
|
|
x: -15
|
|
},
|
|
title: {
|
|
rotation: 270
|
|
}
|
|
};
|
|
// This variable extends the defaultOptions for right axes.
|
|
Axis.defaultRightAxisOptions = {
|
|
labels: {
|
|
x: 15
|
|
},
|
|
title: {
|
|
rotation: 90
|
|
}
|
|
};
|
|
// This variable extends the defaultOptions for bottom axes.
|
|
Axis.defaultBottomAxisOptions = {
|
|
labels: {
|
|
autoRotation: [-45],
|
|
x: 0
|
|
// overflow: undefined,
|
|
// staggerLines: null
|
|
},
|
|
margin: 15,
|
|
title: {
|
|
rotation: 0
|
|
}
|
|
};
|
|
// This variable extends the defaultOptions for top axes.
|
|
Axis.defaultTopAxisOptions = {
|
|
labels: {
|
|
autoRotation: [-45],
|
|
x: 0
|
|
// overflow: undefined
|
|
// staggerLines: null
|
|
},
|
|
margin: 15,
|
|
title: {
|
|
rotation: 0
|
|
}
|
|
};
|
|
// Properties to survive after destroy, needed for Axis.update (#4317,
|
|
// #5773, #5881).
|
|
Axis.keepProps = ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin'];
|
|
return Axis;
|
|
}());
|
|
H.Axis = Axis;
|
|
export default H.Axis;
|