From 70ac1c708b58c9140f76e545f4bdaa1ce6fd737c Mon Sep 17 00:00:00 2001 From: bre1470 <40056287+bre1470@users.noreply.github.com> Date: Tue, 24 Mar 2020 13:25:23 +0100 Subject: [PATCH 01/10] Tools: Migrated LogarithmicAxis to ES6 pattern. --- js/parts/Axis.js | 22 +-- js/parts/LogarithmicAxis.js | 243 ++++++++++++++---------- js/parts/OrdinalAxis.js | 16 +- ts/parts/Axis.ts | 25 +-- ts/parts/LogarithmicAxis.ts | 366 +++++++++++++++++++++--------------- ts/parts/OrdinalAxis.ts | 16 +- ts/parts/axis/types.d.ts | 3 + 7 files changed, 397 insertions(+), 294 deletions(-) diff --git a/js/parts/Axis.js b/js/parts/Axis.js index e06ac2eb10b..9fc14d93256 100644 --- a/js/parts/Axis.js +++ b/js/parts/Axis.js @@ -518,12 +518,6 @@ var Axis = /** @class */ (function () { addEvent(axis, eventType, event); } }); - // extend logarithmic axis - axis.lin2log = options.linearToLogConverter || axis.lin2log; - if (axis.isLog) { - axis.val2lin = axis.log2lin; - axis.lin2val = axis.lin2log; - } fireEvent(this, 'afterInit'); }; /** @@ -965,8 +959,8 @@ var Axis = /** @class */ (function () { // 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, axis.getLogTickPositions(minorTickInterval, paddedTicks[i - 1], paddedTicks[i], true)); + if (i && axis.logarithmic) { + minorTickPositions.push.apply(minorTickPositions, axis.logarithmic.getLogTickPositions(minorTickInterval, paddedTicks[i - 1], paddedTicks[i], true)); } }); } @@ -1542,8 +1536,8 @@ var Axis = /** @class */ (function () { else if (this.isDatetimeAxis) { tickPositions = axis.getTimeTicks(axis.normalizeTimeTickInterval(this.tickInterval, options.units), this.min, this.max, options.startOfWeek, axis.ordinal && axis.ordinal.positions, this.closestPointRange, true); } - else if (this.isLog) { - tickPositions = axis.getLogTickPositions(this.tickInterval, this.min, this.max); + else if (this.isLog && axis.logarithmic) { + tickPositions = axis.logarithmic.getLogTickPositions(this.tickInterval, this.min, this.max); } else { tickPositions = this.getLinearTickPositions(this.tickInterval, this.min, this.max); @@ -5812,10 +5806,8 @@ var Axis = /** @class */ (function () { }; return Axis; }()); -extend(Axis.prototype, { - // Properties to survive after destroy, needed for Axis.update (#4317, - // #5773, #5881). - keepProps: ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin'] -}); +// Properties to survive after destroy, needed for Axis.update (#4317, +// #5773, #5881). +Axis.prototype.keepProps = ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin']; H.Axis = Axis; export default H.Axis; diff --git a/js/parts/LogarithmicAxis.js b/js/parts/LogarithmicAxis.js index 2a6acf554b9..b59ae30fe22 100644 --- a/js/parts/LogarithmicAxis.js +++ b/js/parts/LogarithmicAxis.js @@ -8,114 +8,165 @@ * * */ 'use strict'; -import H from './Globals.js'; +import Axis from './Axis.js'; import U from './Utilities.js'; -var getMagnitude = U.getMagnitude, normalizeTickInterval = U.normalizeTickInterval, pick = U.pick; -var Axis = H.Axis; -/* ************************************************************************** * - * Methods defined on the Axis prototype - * ************************************************************************** */ +var addEvent = U.addEvent, getMagnitude = U.getMagnitude, normalizeTickInterval = U.normalizeTickInterval, pick = U.pick; /* eslint-disable valid-jsdoc */ /** - * Set the tick positions of a logarithmic axis. + * Provides logarithmic support for axes. * * @private - * @function Highcharts.Axis#getLogTickPositions - * @param {number} interval - * @param {number} min - * @param {number} max - * @param {boolean} [minor] - * @return {Array} + * @class */ -Axis.prototype.getLogTickPositions = function (interval, min, max, minor) { - var axis = this, options = axis.options, axisLength = axis.len, - // Since we use this method for both major and minor ticks, - // use a local variable and return the result - positions = []; - // Reset - if (!minor) { - axis._minorAutoInterval = null; +var LogarithmicAxisAdditions = /** @class */ (function () { + /* * + * + * Constructors + * + * */ + function LogarithmicAxisAdditions(axis) { + this.axis = axis; } - // First case: All ticks fall on whole logarithms: 1, 10, 100 etc. - if (interval >= 0.5) { - interval = Math.round(interval); - positions = axis.getLinearTickPositions(interval, min, max); - // Second case: We need intermediary ticks. For example - // 1, 2, 4, 6, 8, 10, 20, 40 etc. - } - else if (interval >= 0.08) { - var roundedMin = Math.floor(min), intermediate, i, j, len, pos, lastPos, break2; - if (interval > 0.3) { - intermediate = [1, 2, 4]; - // 0.2 equals five minor ticks per 1, 10, 100 etc - } - else if (interval > 0.15) { - intermediate = [1, 2, 4, 6, 8]; + /* * + * + * Functions + * + * */ + /** + * Set the tick positions of a logarithmic axis. + */ + LogarithmicAxisAdditions.prototype.getLogTickPositions = function (interval, min, max, minor) { + var log = this; + var axis = log.axis; + var axisLength = axis.len; + var options = axis.options; + // Since we use this method for both major and minor ticks, + // use a local variable and return the result + var positions = []; + // Reset + if (!minor) { + log.minorAutoInterval = void 0; } - else { // 0.1 equals ten minor ticks per 1, 10, 100 etc - intermediate = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + // First case: All ticks fall on whole logarithms: 1, 10, 100 etc. + if (interval >= 0.5) { + interval = Math.round(interval); + positions = axis.getLinearTickPositions(interval, min, max); + // Second case: We need intermediary ticks. For example + // 1, 2, 4, 6, 8, 10, 20, 40 etc. } - for (i = roundedMin; i < max + 1 && !break2; i++) { - len = intermediate.length; - for (j = 0; j < len && !break2; j++) { - pos = axis.log2lin(axis.lin2log(i) * intermediate[j]); - // #1670, lastPos is #3113 - if (pos > min && - (!minor || lastPos <= max) && - typeof lastPos !== 'undefined') { - positions.push(lastPos); - } - if (lastPos > max) { - break2 = true; + else if (interval >= 0.08) { + var roundedMin = Math.floor(min), intermediate, i, j, len, pos, lastPos, break2; + if (interval > 0.3) { + intermediate = [1, 2, 4]; + // 0.2 equals five minor ticks per 1, 10, 100 etc + } + else if (interval > 0.15) { + intermediate = [1, 2, 4, 6, 8]; + } + else { // 0.1 equals ten minor ticks per 1, 10, 100 etc + intermediate = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + } + for (i = roundedMin; i < max + 1 && !break2; i++) { + len = intermediate.length; + for (j = 0; j < len && !break2; j++) { + pos = axis.log2lin(axis.lin2log(i) * intermediate[j]); + // #1670, lastPos is #3113 + if (pos > min && + (!minor || lastPos <= max) && + typeof lastPos !== 'undefined') { + positions.push(lastPos); + } + if (lastPos > max) { + break2 = true; + } + lastPos = pos; } - lastPos = pos; } + // Third case: We are so deep in between whole logarithmic values that + // we might as well handle the tick positions like a linear axis. For + // example 1.01, 1.02, 1.03, 1.04. } - // Third case: We are so deep in between whole logarithmic values that - // we might as well handle the tick positions like a linear axis. For - // example 1.01, 1.02, 1.03, 1.04. - } - else { - var realMin = axis.lin2log(min), realMax = axis.lin2log(max), tickIntervalOption = minor ? - this.getMinorTickInterval() : - options.tickInterval, filteredTickIntervalOption = tickIntervalOption === 'auto' ? - null : - tickIntervalOption, tickPixelIntervalOption = options.tickPixelInterval / (minor ? 5 : 1), totalPixelLength = minor ? - axisLength / axis.tickPositions.length : - axisLength; - interval = pick(filteredTickIntervalOption, axis._minorAutoInterval, (realMax - realMin) * - tickPixelIntervalOption / (totalPixelLength || 1)); - interval = normalizeTickInterval(interval, null, getMagnitude(interval)); - positions = axis.getLinearTickPositions(interval, realMin, realMax).map(axis.log2lin); + else { + var realMin = axis.lin2log(min), realMax = axis.lin2log(max), tickIntervalOption = minor ? + axis.getMinorTickInterval() : + options.tickInterval, filteredTickIntervalOption = tickIntervalOption === 'auto' ? + null : + tickIntervalOption, tickPixelIntervalOption = options.tickPixelInterval / (minor ? 5 : 1), totalPixelLength = minor ? + axisLength / axis.tickPositions.length : + axisLength; + interval = pick(filteredTickIntervalOption, log.minorAutoInterval, (realMax - realMin) * + tickPixelIntervalOption / (totalPixelLength || 1)); + interval = normalizeTickInterval(interval, void 0, getMagnitude(interval)); + positions = axis.getLinearTickPositions(interval, realMin, realMax).map(axis.log2lin); + if (!minor) { + log.minorAutoInterval = interval / 5; + } + } + // Set the axis-level tickInterval variable if (!minor) { - axis._minorAutoInterval = interval / 5; + axis.tickInterval = interval; } + return positions; + }; + LogarithmicAxisAdditions.prototype.lin2log = function (num) { + return Math.pow(10, num); + }; + LogarithmicAxisAdditions.prototype.log2lin = function (num) { + return Math.log(num) / Math.LN10; + }; + return LogarithmicAxisAdditions; +}()); +var LogarithmicAxis = /** @class */ (function () { + function LogarithmicAxis() { } - // Set the axis-level tickInterval variable - if (!minor) { - axis.tickInterval = interval; - } - return positions; -}; -/** - * @private - * @function Highcharts.Axis#log2lin - * - * @param {number} num - * - * @return {number} - */ -Axis.prototype.log2lin = function (num) { - return Math.log(num) / Math.LN10; -}; -/** - * @private - * @function Highcharts.Axis#lin2log - * - * @param {number} num - * - * @return {number} - */ -Axis.prototype.lin2log = function (num) { - return Math.pow(10, num); -}; + /** + * Provides logarithmic support for axes. + * + * @private + */ + LogarithmicAxis.compose = function (AxisClass) { + var axisProto = AxisClass.prototype; + /** + * @deprecated + * @private + * @function Highcharts.Axis#lin2log + * + * @param {number} num + * + * @return {number} + */ + axisProto.lin2log = function (num) { + return Math.pow(10, num); + }; + /** + * @deprecated + * @private + * @function Highcharts.Axis#log2lin + * + * @param {number} num + * + * @return {number} + */ + axisProto.log2lin = function (num) { + return Math.log(num) / Math.LN10; + }; + /* eslint-disable no-invalid-this */ + addEvent(AxisClass, 'init', function () { + var axis = this; + axis.logarithmic = new LogarithmicAxisAdditions(axis); + }); + addEvent(AxisClass, 'afterInit', function () { + var axis = this; + var options = axis.options; + // extend logarithmic axis + axis.lin2log = options.linearToLogConverter || axis.lin2log; + if (axis.isLog) { + axis.val2lin = axis.log2lin; + axis.lin2val = axis.lin2log; + } + }); + }; + return LogarithmicAxis; +}()); +LogarithmicAxis.compose(Axis); // @todo move to factory functions +export default LogarithmicAxis; diff --git a/js/parts/OrdinalAxis.js b/js/parts/OrdinalAxis.js index 1bd8592a6fd..842c2f13a05 100644 --- a/js/parts/OrdinalAxis.js +++ b/js/parts/OrdinalAxis.js @@ -47,7 +47,7 @@ var OrdinalAxisAdditions = /** @class */ (function () { * @private */ OrdinalAxisAdditions.prototype.getExtendedPositions = function () { - var ordinal = this, axis = ordinal.axis, axisPrototype = axis.constructor.prototype, chart = axis.chart, grouping = axis.series[0].currentDataGrouping, ordinalIndex = ordinal.index, key = grouping ? + var ordinal = this, axis = ordinal.axis, axisProto = axis.constructor.prototype, chart = axis.chart, grouping = axis.series[0].currentDataGrouping, ordinalIndex = ordinal.index, key = grouping ? grouping.count + grouping.unitName : 'raw', overscroll = axis.options.overscroll, extremes = axis.getExtremes(), fakeAxis, fakeSeries; // If this is the first time, or the ordinal index is deleted by @@ -72,8 +72,8 @@ var OrdinalAxisAdditions = /** @class */ (function () { ordinal: true }, ordinal: {}, - ordinal2lin: axisPrototype.ordinal2lin, - val2lin: axisPrototype.val2lin // #2590 + ordinal2lin: axisProto.ordinal2lin, + val2lin: axisProto.val2lin // #2590 }; fakeAxis.ordinal.axis = fakeAxis; // Add the fake series to hold the full data, then apply @@ -233,13 +233,13 @@ var OrdinalAxis = /** @class */ (function () { * Series class to use. */ OrdinalAxis.compose = function (AxisClass, ChartClass, SeriesClass) { - var axisPrototype = AxisClass.prototype; + var axisProto = AxisClass.prototype; /** * Calculate the ordinal positions before tick positions are calculated. * * @private */ - axisPrototype.beforeSetTickPositions = function () { + axisProto.beforeSetTickPositions = function () { var axis = this, ordinal = axis.ordinal, len, ordinalPositions = [], uniqueOrdinalPositions, useOrdinal = false, dist, extremes = axis.getExtremes(), min = extremes.min, max = extremes.max, minIndex, maxIndex, slope, hasBreaks = axis.isXAxis && !!axis.options.breaks, isOrdinal = axis.options.ordinal, overscrollPointsRange = Number.MAX_VALUE, ignoreHiddenSeries = axis.chart.options.chart.ignoreHiddenSeries, i, hasBoostedSeries; // Apply the ordinal logic if (isOrdinal || hasBreaks) { // #4167 YAxis is never ordinal ? @@ -516,7 +516,7 @@ var OrdinalAxis = /** @class */ (function () { * * @return {number} */ - axisPrototype.lin2val = function (val, fromIndex) { + axisProto.lin2val = function (val, fromIndex) { var axis = this, ordinal = axis.ordinal, ordinalPositions = ordinal.positions, ret; // the visible range contains only equally spaced values if (!ordinalPositions) { @@ -587,7 +587,7 @@ var OrdinalAxis = /** @class */ (function () { * * @return {number} */ - axisPrototype.val2lin = function (val, toIndex) { + axisProto.val2lin = function (val, toIndex) { var axis = this, ordinal = axis.ordinal, ordinalPositions = ordinal.positions, ret; if (!ordinalPositions) { ret = val; @@ -623,7 +623,7 @@ var OrdinalAxis = /** @class */ (function () { return ret; }; // Record this to prevent overwriting by broken-axis module (#5979) - axisPrototype.ordinal2lin = axisPrototype.val2lin; + axisProto.ordinal2lin = axisProto.val2lin; addEvent(AxisClass, 'afterInit', function () { this.ordinal = new OrdinalAxisAdditions(this); }); diff --git a/ts/parts/Axis.ts b/ts/parts/Axis.ts index 1008a4020a3..cd07a5ac06b 100644 --- a/ts/parts/Axis.ts +++ b/ts/parts/Axis.ts @@ -4156,13 +4156,6 @@ class Axis implements AxisComposition { } }); - // extend logarithmic axis - axis.lin2log = options.linearToLogConverter || axis.lin2log; - if (axis.isLog) { - axis.val2lin = axis.log2lin; - axis.lin2val = axis.lin2log; - } - fireEvent(this, 'afterInit'); } @@ -4777,10 +4770,10 @@ class Axis implements AxisComposition { i: number, paddedTicks: Array ): void { - if (i) { + if (i && axis.logarithmic) { minorTickPositions.push.apply( minorTickPositions, - axis.getLogTickPositions( + axis.logarithmic.getLogTickPositions( minorTickInterval, paddedTicks[i - 1], paddedTicks[i], @@ -5603,8 +5596,8 @@ class Axis implements AxisComposition { this.closestPointRange, true ); - } else if (this.isLog) { - tickPositions = axis.getLogTickPositions( + } else if (this.isLog && axis.logarithmic) { + tickPositions = axis.logarithmic.getLogTickPositions( this.tickInterval, this.min as any, this.max as any @@ -7659,13 +7652,9 @@ interface Axis { keepProps: Array; } -extend(Axis.prototype, { - - // Properties to survive after destroy, needed for Axis.update (#4317, - // #5773, #5881). - keepProps: ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin'] - -}); +// Properties to survive after destroy, needed for Axis.update (#4317, +// #5773, #5881). +Axis.prototype.keepProps = ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin']; H.Axis = Axis as any; diff --git a/ts/parts/LogarithmicAxis.ts b/ts/parts/LogarithmicAxis.ts index 5502dbf0abc..4c78bac07ae 100644 --- a/ts/parts/LogarithmicAxis.ts +++ b/ts/parts/LogarithmicAxis.ts @@ -10,7 +10,14 @@ 'use strict'; -import H from './Globals.js'; +import Axis from './Axis.js'; +import U from './Utilities.js'; +const { + addEvent, + getMagnitude, + normalizeTickInterval, + pick +} = U; /** * Internal types @@ -19,180 +26,241 @@ import H from './Globals.js'; declare global { namespace Highcharts { interface Axis { - _minorAutoInterval?: (null|number); - getLogTickPositions( - interval: number, - min: number, - max: number, - minor?: boolean - ): Array; + /** @deprecated */ lin2log(num: number): number; + /** @deprecated */ log2lin(num: number): number; } } } -import U from './Utilities.js'; -const { - getMagnitude, - normalizeTickInterval, - pick -} = U; - -var Axis = H.Axis; - -/* ************************************************************************** * - * Methods defined on the Axis prototype - * ************************************************************************** */ - /* eslint-disable valid-jsdoc */ /** - * Set the tick positions of a logarithmic axis. + * Provides logarithmic support for axes. * * @private - * @function Highcharts.Axis#getLogTickPositions - * @param {number} interval - * @param {number} min - * @param {number} max - * @param {boolean} [minor] - * @return {Array} + * @class */ -Axis.prototype.getLogTickPositions = function ( - this: Highcharts.Axis, - interval: number, - min: number, - max: number, - minor?: boolean -): Array { - var axis = this, - options = axis.options, - axisLength = axis.len, - // Since we use this method for both major and minor ticks, - // use a local variable and return the result - positions = []; +class LogarithmicAxisAdditions { - // Reset - if (!minor) { - axis._minorAutoInterval = null; + /* * + * + * Constructors + * + * */ + + public constructor(axis: LogarithmicAxis) { + this.axis = axis; } - // First case: All ticks fall on whole logarithms: 1, 10, 100 etc. - if (interval >= 0.5) { - interval = Math.round(interval); - positions = axis.getLinearTickPositions(interval, min, max); - - // Second case: We need intermediary ticks. For example - // 1, 2, 4, 6, 8, 10, 20, 40 etc. - } else if (interval >= 0.08) { - var roundedMin = Math.floor(min), - intermediate, - i, - j, - len, - pos, - lastPos, - break2; - - if (interval > 0.3) { - intermediate = [1, 2, 4]; - - // 0.2 equals five minor ticks per 1, 10, 100 etc - } else if (interval > 0.15) { - intermediate = [1, 2, 4, 6, 8]; - } else { // 0.1 equals ten minor ticks per 1, 10, 100 etc - intermediate = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + /* * + * + * Properties + * + * */ + + public axis: LogarithmicAxis; + public minorAutoInterval?: number; + + /* * + * + * Functions + * + * */ + + /** + * Set the tick positions of a logarithmic axis. + */ + public getLogTickPositions( + interval: number, + min: number, + max: number, + minor?: boolean + ): Array { + const log = this; + const axis = log.axis; + const axisLength = axis.len; + const options = axis.options; + + // Since we use this method for both major and minor ticks, + // use a local variable and return the result + let positions = []; + + // Reset + if (!minor) { + log.minorAutoInterval = void 0; } - for (i = roundedMin; i < max + 1 && !break2; i++) { - len = intermediate.length; - for (j = 0; j < len && !break2; j++) { - pos = axis.log2lin(axis.lin2log(i) * intermediate[j]); - // #1670, lastPos is #3113 - if ( - pos > min && - (!minor || (lastPos as any) <= max) && - typeof lastPos !== 'undefined' - ) { - positions.push(lastPos); - } + // First case: All ticks fall on whole logarithms: 1, 10, 100 etc. + if (interval >= 0.5) { + interval = Math.round(interval); + positions = axis.getLinearTickPositions(interval, min, max); + + // Second case: We need intermediary ticks. For example + // 1, 2, 4, 6, 8, 10, 20, 40 etc. + } else if (interval >= 0.08) { + var roundedMin = Math.floor(min), + intermediate, + i, + j, + len, + pos, + lastPos, + break2; + + if (interval > 0.3) { + intermediate = [1, 2, 4]; - if ((lastPos as any) > max) { - break2 = true; + // 0.2 equals five minor ticks per 1, 10, 100 etc + } else if (interval > 0.15) { + intermediate = [1, 2, 4, 6, 8]; + } else { // 0.1 equals ten minor ticks per 1, 10, 100 etc + intermediate = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + } + + for (i = roundedMin; i < max + 1 && !break2; i++) { + len = intermediate.length; + for (j = 0; j < len && !break2; j++) { + pos = axis.log2lin(axis.lin2log(i) * intermediate[j]); + // #1670, lastPos is #3113 + if ( + pos > min && + (!minor || (lastPos as any) <= max) && + typeof lastPos !== 'undefined' + ) { + positions.push(lastPos); + } + + if ((lastPos as any) > max) { + break2 = true; + } + lastPos = pos; } - lastPos = pos; } - } - // Third case: We are so deep in between whole logarithmic values that - // we might as well handle the tick positions like a linear axis. For - // example 1.01, 1.02, 1.03, 1.04. - } else { - var realMin = axis.lin2log(min), - realMax = axis.lin2log(max), - tickIntervalOption = minor ? - this.getMinorTickInterval() : - options.tickInterval, - filteredTickIntervalOption = tickIntervalOption === 'auto' ? - null : - tickIntervalOption, - tickPixelIntervalOption = - (options.tickPixelInterval as any) / (minor ? 5 : 1), - totalPixelLength = minor ? - axisLength / axis.tickPositions.length : - axisLength; - - interval = pick( - filteredTickIntervalOption, - axis._minorAutoInterval, - (realMax - realMin) * - tickPixelIntervalOption / (totalPixelLength || 1) - ); - - interval = normalizeTickInterval( - interval, - null as any, - getMagnitude(interval) - ); - - positions = axis.getLinearTickPositions( - interval, - realMin, - realMax - ).map(axis.log2lin); + // Third case: We are so deep in between whole logarithmic values that + // we might as well handle the tick positions like a linear axis. For + // example 1.01, 1.02, 1.03, 1.04. + } else { + var realMin = axis.lin2log(min), + realMax = axis.lin2log(max), + tickIntervalOption = minor ? + axis.getMinorTickInterval() : + options.tickInterval, + filteredTickIntervalOption = tickIntervalOption === 'auto' ? + null : + tickIntervalOption, + tickPixelIntervalOption = + (options.tickPixelInterval as any) / (minor ? 5 : 1), + totalPixelLength = minor ? + axisLength / axis.tickPositions.length : + axisLength; + interval = pick( + filteredTickIntervalOption, + log.minorAutoInterval, + (realMax - realMin) * + tickPixelIntervalOption / (totalPixelLength || 1) + ); + + interval = normalizeTickInterval( + interval, + void 0, + getMagnitude(interval) + ); + + positions = axis.getLinearTickPositions( + interval, + realMin, + realMax + ).map(axis.log2lin); + + if (!minor) { + log.minorAutoInterval = interval / 5; + } + } + + // Set the axis-level tickInterval variable if (!minor) { - axis._minorAutoInterval = interval / 5; + axis.tickInterval = interval; } + return positions; } - // Set the axis-level tickInterval variable - if (!minor) { - axis.tickInterval = interval; + public lin2log(num: number): number { + return Math.pow(10, num); } - return positions; -}; -/** - * @private - * @function Highcharts.Axis#log2lin - * - * @param {number} num - * - * @return {number} - */ -Axis.prototype.log2lin = function (this: Highcharts.Axis, num: number): number { - return Math.log(num) / Math.LN10; -}; + public log2lin(num: number): number { + return Math.log(num) / Math.LN10; + } -/** - * @private - * @function Highcharts.Axis#lin2log - * - * @param {number} num - * - * @return {number} - */ -Axis.prototype.lin2log = function (this: Highcharts.Axis, num: number): number { - return Math.pow(10, num); -}; +} + +class LogarithmicAxis { + + /** + * Provides logarithmic support for axes. + * + * @private + */ + public static compose(AxisClass: typeof Axis): void { + + const axisProto = AxisClass.prototype as LogarithmicAxis; + + /** + * @deprecated + * @private + * @function Highcharts.Axis#lin2log + * + * @param {number} num + * + * @return {number} + */ + axisProto.lin2log = function (this: Highcharts.Axis, num: number): number { + return Math.pow(10, num); + }; + + /** + * @deprecated + * @private + * @function Highcharts.Axis#log2lin + * + * @param {number} num + * + * @return {number} + */ + axisProto.log2lin = function (this: Highcharts.Axis, num: number): number { + return Math.log(num) / Math.LN10; + }; + + /* eslint-disable no-invalid-this */ + + addEvent(AxisClass, 'init', function (): void { + const axis = this as LogarithmicAxis; + axis.logarithmic = new LogarithmicAxisAdditions(axis); + }); + + addEvent(AxisClass, 'afterInit', function (): void { + const axis = this as LogarithmicAxis; + const options = axis.options; + // extend logarithmic axis + axis.lin2log = options.linearToLogConverter || axis.lin2log; + if (axis.isLog) { + axis.val2lin = axis.log2lin; + axis.lin2val = axis.lin2log; + } + }); + } +} + +interface LogarithmicAxis extends Axis { + logarithmic: LogarithmicAxisAdditions; + lin2log(num: number): number; + log2lin(num: number): number; +} + +LogarithmicAxis.compose(Axis); // @todo move to factory functions + +export default LogarithmicAxis; diff --git a/ts/parts/OrdinalAxis.ts b/ts/parts/OrdinalAxis.ts index 286794e2ae2..587273d6b55 100644 --- a/ts/parts/OrdinalAxis.ts +++ b/ts/parts/OrdinalAxis.ts @@ -107,7 +107,7 @@ class OrdinalAxisAdditions { public getExtendedPositions(): Array { var ordinal = this, axis = ordinal.axis, - axisPrototype = axis.constructor.prototype, + axisProto = axis.constructor.prototype, chart = axis.chart, grouping = axis.series[0].currentDataGrouping, ordinalIndex = ordinal.index, @@ -144,8 +144,8 @@ class OrdinalAxisAdditions { ordinal: true }, ordinal: {}, - ordinal2lin: axisPrototype.ordinal2lin, // #6276 - val2lin: axisPrototype.val2lin // #2590 + ordinal2lin: axisProto.ordinal2lin, // #6276 + val2lin: axisProto.val2lin // #2590 } as any; fakeAxis.ordinal.axis = fakeAxis; @@ -353,14 +353,14 @@ class OrdinalAxis { SeriesClass: typeof Series ): void { - const axisPrototype = AxisClass.prototype as OrdinalAxis; + const axisProto = AxisClass.prototype as OrdinalAxis; /** * Calculate the ordinal positions before tick positions are calculated. * * @private */ - axisPrototype.beforeSetTickPositions = function (): void { + axisProto.beforeSetTickPositions = function (): void { var axis = this, ordinal = axis.ordinal, len, @@ -790,7 +790,7 @@ class OrdinalAxis { * * @return {number} */ - axisPrototype.lin2val = function ( + axisProto.lin2val = function ( val: number, fromIndex?: boolean ): number { @@ -881,7 +881,7 @@ class OrdinalAxis { * * @return {number} */ - axisPrototype.val2lin = function ( + axisProto.val2lin = function ( val: number, toIndex?: boolean ): number { @@ -930,7 +930,7 @@ class OrdinalAxis { return ret; }; // Record this to prevent overwriting by broken-axis module (#5979) - axisPrototype.ordinal2lin = axisPrototype.val2lin; + axisProto.ordinal2lin = axisProto.val2lin; addEvent(AxisClass, 'afterInit', function (): void { this.ordinal = new OrdinalAxisAdditions(this as OrdinalAxis); diff --git a/ts/parts/axis/types.d.ts b/ts/parts/axis/types.d.ts index 5e91dc839eb..dd3ab3e3e61 100644 --- a/ts/parts/axis/types.d.ts +++ b/ts/parts/axis/types.d.ts @@ -10,11 +10,13 @@ import type Axis from '../Axis'; import type HiddenAxis from '../../parts-more/HiddenAxis'; +import type LogarithmicAxis from '../LogarithmicAxis'; import type OrdinalAxis from '../OrdinalAxis'; import type RadialAxis from '../../parts-more/RadialAxis'; import type ScrollbarAxis from '../ScrollbarAxis'; export interface AxisComposition { + logarithmic?: LogarithmicAxis['logarithmic']; ordinal?: OrdinalAxis['ordinal']; scrollbar?: ScrollbarAxis['scrollbar']; } @@ -25,6 +27,7 @@ export interface AxisComposition { export type AxisType = ( Axis| HiddenAxis| + LogarithmicAxis| OrdinalAxis| RadialAxis| ScrollbarAxis From 94db9decb1d97f1fb5f112d84f6a8c2a16f9d7ae Mon Sep 17 00:00:00 2001 From: bre1470 <40056287+bre1470@users.noreply.github.com> Date: Wed, 25 Mar 2020 21:42:26 +0100 Subject: [PATCH 02/10] Improved keepProps handling in Axis. --- js/modules/drag-panes.src.js | 2 +- js/modules/parallel-coordinates.src.js | 2 +- js/parts-map/ColorAxis.js | 2 +- js/parts/Axis.js | 20 ++++++++++++---- ts/modules/drag-panes.src.ts | 2 +- ts/modules/parallel-coordinates.src.ts | 2 +- ts/parts-map/ColorAxis.ts | 2 +- ts/parts/Axis.ts | 32 ++++++++++++++++++-------- 8 files changed, 44 insertions(+), 20 deletions(-) diff --git a/js/modules/drag-panes.src.js b/js/modules/drag-panes.src.js index d193366adf2..f42c1c2c5f5 100644 --- a/js/modules/drag-panes.src.js +++ b/js/modules/drag-panes.src.js @@ -453,7 +453,7 @@ var AxisResizer = /** @class */ (function () { return AxisResizer; }()); // Keep resizer reference on axis update -Axis.prototype.keepProps.push('resizer'); +Axis.keepProps.push('resizer'); /* eslint-disable no-invalid-this */ // Add new AxisResizer, update or remove it addEvent(Axis, 'afterRender', function () { diff --git a/js/modules/parallel-coordinates.src.js b/js/modules/parallel-coordinates.src.js index 30f5ce0d8e8..0e95ce2390c 100644 --- a/js/modules/parallel-coordinates.src.js +++ b/js/modules/parallel-coordinates.src.js @@ -203,7 +203,7 @@ extend(ChartProto, /** @lends Highcharts.Chart.prototype */ { } }); // On update, keep parallelPosition. -AxisProto.keepProps.push('parallelPosition'); +Axis.keepProps.push('parallelPosition'); // Update default options with predefined for a parallel coords. addEvent(Axis, 'afterSetOptions', function (e) { var axis = this, chart = axis.chart, axisPosition = ['left', 'width', 'height', 'top']; diff --git a/js/parts-map/ColorAxis.js b/js/parts-map/ColorAxis.js index 90945af5f33..27715d52259 100644 --- a/js/parts-map/ColorAxis.js +++ b/js/parts-map/ColorAxis.js @@ -470,7 +470,7 @@ extend(ColorAxis.prototype, { 'legendItemWidth', 'legendItem', 'legendSymbol' - ].concat(Axis.prototype.keepProps), + ].concat(Axis.keepProps), /* eslint-disable no-invalid-this, valid-jsdoc */ /** * Initializes the color axis. diff --git a/js/parts/Axis.js b/js/parts/Axis.js index 9fc14d93256..b6aac46bcf1 100644 --- a/js/parts/Axis.js +++ b/js/parts/Axis.js @@ -2816,6 +2816,18 @@ var Axis = /** @class */ (function () { series.isDirty = true; }); }; + /** + * Returns an array of axis properties, that should be untouched during + * reinitialization. + * + * @private + * @function Highcharts.Axis#getKeepProps + * + * @return {Array} + */ + 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. @@ -2862,7 +2874,7 @@ var Axis = /** @class */ (function () { } // Delete all properties and fall back to the prototype. objectEach(axis, function (val, key) { - if (axis.keepProps.indexOf(key) === -1) { + if (axis.getKeepProps().indexOf(key) === -1) { delete axis[key]; } }); @@ -5804,10 +5816,10 @@ var Axis = /** @class */ (function () { rotation: 0 } }; + // Properties to survive after destroy, needed for Axis.update (#4317, + // #5773, #5881). + Axis.keepProps = ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin']; return Axis; }()); -// Properties to survive after destroy, needed for Axis.update (#4317, -// #5773, #5881). -Axis.prototype.keepProps = ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin']; H.Axis = Axis; export default H.Axis; diff --git a/ts/modules/drag-panes.src.ts b/ts/modules/drag-panes.src.ts index 22f349746eb..99d9c7ecbc8 100644 --- a/ts/modules/drag-panes.src.ts +++ b/ts/modules/drag-panes.src.ts @@ -676,7 +676,7 @@ class AxisResizer { } // Keep resizer reference on axis update -Axis.prototype.keepProps.push('resizer'); +Axis.keepProps.push('resizer'); /* eslint-disable no-invalid-this */ // Add new AxisResizer, update or remove it diff --git a/ts/modules/parallel-coordinates.src.ts b/ts/modules/parallel-coordinates.src.ts index 25696892b55..b8d274e697f 100644 --- a/ts/modules/parallel-coordinates.src.ts +++ b/ts/modules/parallel-coordinates.src.ts @@ -316,7 +316,7 @@ extend(ChartProto, /** @lends Highcharts.Chart.prototype */ { // On update, keep parallelPosition. -AxisProto.keepProps.push('parallelPosition'); +Axis.keepProps.push('parallelPosition'); // Update default options with predefined for a parallel coords. addEvent(Axis, 'afterSetOptions', function ( diff --git a/ts/parts-map/ColorAxis.ts b/ts/parts-map/ColorAxis.ts index e1d20714210..fb38bc09230 100644 --- a/ts/parts-map/ColorAxis.ts +++ b/ts/parts-map/ColorAxis.ts @@ -655,7 +655,7 @@ extend(ColorAxis.prototype, { 'legendItemWidth', 'legendItem', 'legendSymbol' - ].concat(Axis.prototype.keepProps), + ].concat(Axis.keepProps), /* eslint-disable no-invalid-this, valid-jsdoc */ diff --git a/ts/parts/Axis.ts b/ts/parts/Axis.ts index cd07a5ac06b..aa273afa9c5 100644 --- a/ts/parts/Axis.ts +++ b/ts/parts/Axis.ts @@ -320,6 +320,7 @@ declare global { public static defaultRightAxisOptions: AxisOptions; public static defaultTopAxisOptions: AxisOptions; public static defaultYAxisOptions: YAxisOptions; + public static keepProps: Array; public constructor(chart: Chart, userOptions: AxisOptions); public _addedPlotLB?: boolean; public allowZoomOutside?: boolean; @@ -360,7 +361,7 @@ declare global { public isRadial?: boolean; public isXAxis?: boolean; public isZAxis?: boolean; - public keepProps: Array; + public keepProps?: Array; public labelAlign?: AlignValue; public labelEdge: Array; public labelFormatter: ( @@ -442,6 +443,7 @@ declare global { public generateTick(pos: number, i?: number): void; public getClosest(): number; public getExtremes(): ExtremesObject; + public getKeepProps(): Array; public getLinePath(lineWidth: number): SVGPathArray; public getLinearTickPositions( tickInterval: number, @@ -3767,6 +3769,10 @@ class Axis implements AxisComposition { } }; + // Properties to survive after destroy, needed for Axis.update (#4317, + // #5773, #5881). + public static keepProps = ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin']; + /* * * * Constructors @@ -3820,6 +3826,7 @@ class Axis implements AxisComposition { public isRadial?: boolean; public isXAxis?: boolean; public isZAxis?: boolean; + public keepProps?: Array; public labelAlign?: Highcharts.AlignValue; public labelEdge: Array = void 0 as any; // @todo public labelFormatter: ( @@ -7412,6 +7419,19 @@ class Axis implements AxisComposition { } + /** + * Returns an array of axis properties, that should be untouched during + * reinitialization. + * + * @private + * @function Highcharts.Axis#getKeepProps + * + * @return {Array} + */ + public getKeepProps(): Array { + return (this.keepProps || Axis.keepProps); + } + /** * Destroys an Axis instance. See {@link Axis#remove} for the API endpoint * to fully remove the axis. @@ -7482,7 +7502,7 @@ class Axis implements AxisComposition { // Delete all properties and fall back to the prototype. objectEach(axis, function (val: any, key: string): void { - if (axis.keepProps.indexOf(key) === -1) { + if (axis.getKeepProps().indexOf(key) === -1) { delete (axis as any)[key]; } }); @@ -7648,14 +7668,6 @@ class Axis implements AxisComposition { } } -interface Axis { - keepProps: Array; -} - -// Properties to survive after destroy, needed for Axis.update (#4317, -// #5773, #5881). -Axis.prototype.keepProps = ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin']; - H.Axis = Axis as any; export default H.Axis; From 0d50481410bf5853f73280468385eadb81328e47 Mon Sep 17 00:00:00 2001 From: bre1470 <40056287+bre1470@users.noreply.github.com> Date: Thu, 26 Mar 2020 09:52:00 +0100 Subject: [PATCH 03/10] Migrated Axis.isLog to LogarithmicAxis. --- js/modules/boost/wgl-renderer.js | 4 +- js/modules/solid-gauge.src.js | 2 +- js/parts-3d/Series.js | 2 +- js/parts-map/ColorAxis.js | 2 +- js/parts-more/BubbleSeries.js | 2 +- js/parts/Axis.js | 56 ++++++++++++++-------------- js/parts/LogarithmicAxis.js | 12 ++++-- js/parts/PlotLineOrBand.js | 8 ++-- js/parts/Series.js | 2 +- js/parts/StockChart.js | 5 ++- js/parts/Tick.js | 2 +- ts/modules/boost/wgl-renderer.ts | 4 +- ts/modules/solid-gauge.src.ts | 2 +- ts/parts-3d/Series.ts | 2 +- ts/parts-map/ColorAxis.ts | 2 +- ts/parts-more/BubbleSeries.ts | 2 +- ts/parts/Axis.ts | 64 +++++++++++++++----------------- ts/parts/LogarithmicAxis.ts | 14 +++++-- ts/parts/PlotLineOrBand.ts | 8 ++-- ts/parts/Series.ts | 2 +- ts/parts/StockChart.ts | 4 +- ts/parts/Tick.ts | 2 +- 22 files changed, 105 insertions(+), 98 deletions(-) diff --git a/js/modules/boost/wgl-renderer.js b/js/modules/boost/wgl-renderer.js index e298385e84f..4281f3dbe5f 100644 --- a/js/modules/boost/wgl-renderer.js +++ b/js/modules/boost/wgl-renderer.js @@ -732,7 +732,7 @@ function GLRenderer(postRenderCallback) { shader.setUniform('xAxisLen', axis.len); shader.setUniform('xAxisPos', axis.pos); shader.setUniform('xAxisCVSCoord', (!axis.horiz)); - shader.setUniform('xAxisIsLog', axis.isLog); + shader.setUniform('xAxisIsLog', (!!axis.logarithmic)); shader.setUniform('xAxisReversed', (!!axis.reversed)); } /** @@ -751,7 +751,7 @@ function GLRenderer(postRenderCallback) { shader.setUniform('yAxisLen', axis.len); shader.setUniform('yAxisPos', axis.pos); shader.setUniform('yAxisCVSCoord', (!axis.horiz)); - shader.setUniform('yAxisIsLog', axis.isLog); + shader.setUniform('yAxisIsLog', (!!axis.logarithmic)); shader.setUniform('yAxisReversed', (!!axis.reversed)); } /** diff --git a/js/modules/solid-gauge.src.js b/js/modules/solid-gauge.src.js index c4d4694c862..bc2d8d5df07 100644 --- a/js/modules/solid-gauge.src.js +++ b/js/modules/solid-gauge.src.js @@ -117,7 +117,7 @@ colorAxisMethods = { } } else { - if (this.isLog) { + if (this.logarithmic) { value = this.val2lin(value); } pos = 1 - ((this.max - value) / (this.max - this.min)); diff --git a/js/parts-3d/Series.js b/js/parts-3d/Series.js index 26fb064a48b..43c001e4510 100644 --- a/js/parts-3d/Series.js +++ b/js/parts-3d/Series.js @@ -27,7 +27,7 @@ H.Series.prototype.translate3dPoints = function () { for (i = 0; i < series.data.length; i++) { rawPoint = series.data[i]; if (zAxis && zAxis.translate) { - zValue = zAxis.isLog && zAxis.val2lin ? + zValue = zAxis.logarithmic && zAxis.val2lin ? zAxis.val2lin(rawPoint.z) : rawPoint.z; // #4562 rawPoint.plotZ = zAxis.translate(zValue); diff --git a/js/parts-map/ColorAxis.js b/js/parts-map/ColorAxis.js index 27715d52259..e1c8f727e9e 100644 --- a/js/parts-map/ColorAxis.js +++ b/js/parts-map/ColorAxis.js @@ -636,7 +636,7 @@ extend(ColorAxis.prototype, { * @private */ normalizedValue: function (value) { - if (this.isLog) { + if (this.logarithmic) { value = this.val2lin(value); } return 1 - ((this.max - value) / diff --git a/js/parts-more/BubbleSeries.js b/js/parts-more/BubbleSeries.js index d14343db20d..093815225d2 100644 --- a/js/parts-more/BubbleSeries.js +++ b/js/parts-more/BubbleSeries.js @@ -465,7 +465,7 @@ Axis.prototype.beforePadding = function () { } }); // Apply the padding to the min and max properties - if (activeSeries.length && range > 0 && !this.isLog) { + if (activeSeries.length && range > 0 && !this.logarithmic) { pxMax -= axisLength; transA *= (axisLength + Math.max(0, pxMin) - // #8901 diff --git a/js/parts/Axis.js b/js/parts/Axis.js index b6aac46bcf1..06823c74800 100644 --- a/js/parts/Axis.js +++ b/js/parts/Axis.js @@ -260,7 +260,6 @@ var Axis = /** @class */ (function () { this.height = void 0; this.isDatetimeAxis = void 0; this.isLinked = void 0; - this.isLog = void 0; this.labelEdge = void 0; // @todo this.labelFormatter = void 0; this.left = void 0; @@ -425,9 +424,8 @@ var Axis = /** @class */ (function () { // Placeholder for plotlines and plotbands groups axis.plotLinesAndBandsGroups = {}; // Shorthand types - axis.isLog = type === 'logarithmic'; axis.isDatetimeAxis = isDatetimeAxis; - axis.positiveValuesOnly = axis.isLog && !axis.allowNegativeLog; + axis.positiveValuesOnly = !!(axis.logarithmic && !axis.allowNegativeLog); // Flag, if axis is linked to another axis axis.isLinked = defined(options.linkedTo); /** @@ -560,7 +558,7 @@ var Axis = /** @class */ (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.isLog ? + numericSymbolDetector = axis.logarithmic ? Math.abs(value) : axis.tickInterval; var chart = this.chart; @@ -727,7 +725,7 @@ var Axis = /** @class */ (function () { 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.isBroken || - (axis.isLog && handleLog)) && axis.lin2val; + (axis.logarithmic && handleLog)) && axis.lin2val; if (!localA) { localA = axis.transA; } @@ -955,7 +953,7 @@ var Axis = /** @class */ (function () { // 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 - if (axis.isLog) { + if (axis.logarithmic) { // For each interval in the major ticks, compute the minor ticks // separately. this.paddedTicks.forEach(function (_pos, i, paddedTicks) { @@ -998,7 +996,7 @@ var Axis = /** @class */ (function () { // Set the automatic minimum range based on the closest point distance if (axis.isXAxis && typeof axis.minRange === 'undefined' && - !axis.isLog) { + !axis.logarithmic) { if (defined(options.min) || defined(options.max)) { axis.minRange = null; // don't do this again } @@ -1034,8 +1032,8 @@ var Axis = /** @class */ (function () { ]; // If space is available, stay within the data range if (spaceAvailable) { - minArgs[2] = axis.isLog ? - axis.log2lin(axis.dataMin) : + minArgs[2] = axis.logarithmic ? + axis.logarithmic.log2lin(axis.dataMin) : axis.dataMin; } min = arrayMax(minArgs); @@ -1045,8 +1043,8 @@ var Axis = /** @class */ (function () { ]; // If space is availabe, stay within the data range if (spaceAvailable) { - maxArgs[2] = axis.isLog ? - axis.log2lin(axis.dataMax) : + maxArgs[2] = axis.logarithmic ? + axis.logarithmic.log2lin(axis.dataMax) : axis.dataMax; } max = arrayMin(maxArgs); @@ -1277,7 +1275,7 @@ var Axis = /** @class */ (function () { * @fires Highcharts.Axis#event:foundExtremes */ Axis.prototype.setTickInterval = function (secondPass) { - var axis = this, chart = axis.chart, options = axis.options, isLog = axis.isLog, isDatetimeAxis = axis.isDatetimeAxis, 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; + var axis = this, chart = axis.chart, options = axis.options, isDatetimeAxis = axis.isDatetimeAxis, 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 (!isDatetimeAxis && !categories && !isLinked) { this.getTickAmount(); } @@ -1311,7 +1309,7 @@ var Axis = /** @class */ (function () { axis.min = pick(hardMin, thresholdMin, axis.dataMin); axis.max = pick(hardMax, thresholdMax, axis.dataMax); } - if (isLog) { + if (axis.logarithmic) { if (axis.positiveValuesOnly && !secondPass && Math.min(axis.min, pick(axis.dataMin, axis.min)) <= 0) { // #978 @@ -1457,7 +1455,7 @@ var Axis = /** @class */ (function () { axis.tickInterval = minTickInterval; } // for linear axes, get magnitude and normalize the interval - if (!isDatetimeAxis && !isLog && !tickIntervalOption) { + if (!isDatetimeAxis && !axis.logarithmic && !tickIntervalOption) { axis.tickInterval = normalizeTickInterval(axis.tickInterval, null, getMagnitude(axis.tickInterval), // If the tick interval is between 0.5 and 5 and the axis max is // in the order of thousands, chances are we are dealing with @@ -1536,7 +1534,7 @@ var Axis = /** @class */ (function () { else if (this.isDatetimeAxis) { tickPositions = axis.getTimeTicks(axis.normalizeTimeTickInterval(this.tickInterval, options.units), this.min, this.max, options.startOfWeek, axis.ordinal && axis.ordinal.positions, this.closestPointRange, true); } - else if (this.isLog && axis.logarithmic) { + else if (axis.logarithmic) { tickPositions = axis.logarithmic.getLogTickPositions(this.tickInterval, this.min, this.max); } else { @@ -1636,8 +1634,8 @@ var Axis = /** @class */ (function () { * True if there are other axes. */ Axis.prototype.alignToOthers = function () { - var others = // Whether there is another axis to pair with this one - {}, hasOther, options = this.options; + 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 && @@ -1647,7 +1645,7 @@ var Axis = /** @class */ (function () { options.endOnTick !== false && // Don't try to align ticks on a log axis, they are not evenly // spaced (#6021) - !this.isLog) { + !axis.logarithmic) { this.chart[this.coll].forEach(function (axis) { var otherOptions = axis.options, horiz = axis.horiz, key = [ horiz ? otherOptions.left : otherOptions.top, @@ -1675,11 +1673,11 @@ var Axis = /** @class */ (function () { * @function Highcharts.Axis#getTickAmount */ Axis.prototype.getTickAmount = function () { - var options = this.options, tickAmount = options.tickAmount, tickPixelInterval = options.tickPixelInterval; + var axis = this, options = this.options, tickAmount = options.tickAmount, tickPixelInterval = options.tickPixelInterval; if (!defined(options.tickInterval) && this.len < tickPixelInterval && !this.isRadial && - !this.isLog && + !axis.logarithmic && options.startOnTick && options.endOnTick) { tickAmount = 2; @@ -1960,13 +1958,13 @@ var Axis = /** @class */ (function () { * An object containing extremes information. */ Axis.prototype.getExtremes = function () { - var axis = this, isLog = axis.isLog; + var axis = this; return { - min: isLog ? - correctFloat(axis.lin2log(axis.min)) : + min: axis.logarithmic ? + correctFloat(axis.logarithmic.lin2log(axis.min)) : axis.min, - max: isLog ? - correctFloat(axis.lin2log(axis.max)) : + max: axis.logarithmic ? + correctFloat(axis.logarithmic.lin2log(axis.max)) : axis.max, dataMin: axis.dataMin, dataMax: axis.dataMax, @@ -1988,7 +1986,7 @@ var Axis = /** @class */ (function () { * stay within the axis bounds. */ Axis.prototype.getThreshold = function (threshold) { - var axis = this, isLog = axis.isLog, realMin = isLog ? axis.lin2log(axis.min) : axis.min, realMax = isLog ? axis.lin2log(axis.max) : axis.max; + var axis = this, realMin = axis.logarithmic ? axis.logarithmic.lin2log(axis.min) : axis.min, realMax = axis.logarithmic ? axis.logarithmic.lin2log(axis.max) : axis.max; if (threshold === null || threshold === -Infinity) { threshold = realMin; } @@ -2666,7 +2664,7 @@ var Axis = /** @class */ (function () { * @fires Highcharts.Axis#event:afterRender */ Axis.prototype.render = function () { - var axis = this, chart = axis.chart, renderer = chart.renderer, options = axis.options, isLog = axis.isLog, 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; + var axis = this, chart = axis.chart, 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; @@ -2718,8 +2716,8 @@ var Axis = /** @class */ (function () { } from = pos + tickmarkOffset; // #949 alternateBands[pos].options = { - from: isLog ? axis.lin2log(from) : from, - to: isLog ? axis.lin2log(to) : to, + from: axis.logarithmic ? axis.logarithmic.lin2log(from) : from, + to: axis.logarithmic ? axis.logarithmic.lin2log(to) : to, color: alternateGridColor }; alternateBands[pos].render(); diff --git a/js/parts/LogarithmicAxis.js b/js/parts/LogarithmicAxis.js index b59ae30fe22..7760fe8a855 100644 --- a/js/parts/LogarithmicAxis.js +++ b/js/parts/LogarithmicAxis.js @@ -151,16 +151,22 @@ var LogarithmicAxis = /** @class */ (function () { return Math.log(num) / Math.LN10; }; /* eslint-disable no-invalid-this */ - addEvent(AxisClass, 'init', function () { + addEvent(AxisClass, 'init', function (e) { var axis = this; - axis.logarithmic = new LogarithmicAxisAdditions(axis); + var options = e.userOptions; + if (options.type === 'logarithmic') { + axis.logarithmic = new LogarithmicAxisAdditions(axis); + } + else { + axis.logarithmic = void 0; + } }); addEvent(AxisClass, 'afterInit', function () { var axis = this; var options = axis.options; // extend logarithmic axis axis.lin2log = options.linearToLogConverter || axis.lin2log; - if (axis.isLog) { + if (axis.logarithmic) { axis.val2lin = axis.log2lin; axis.lin2val = axis.lin2log; } diff --git a/js/parts/PlotLineOrBand.js b/js/parts/PlotLineOrBand.js index 8aabce1a9c7..6fa1af1dc62 100644 --- a/js/parts/PlotLineOrBand.js +++ b/js/parts/PlotLineOrBand.js @@ -66,10 +66,10 @@ var PlotLineOrBand = /** @class */ (function () { (options.className || '') }, groupAttribs = {}, renderer = axis.chart.renderer, groupName = isBand ? 'bands' : 'lines', group; // logarithmic conversion - if (axis.isLog) { - from = axis.log2lin(from); - to = axis.log2lin(to); - value = axis.log2lin(value); + if (axis.logarithmic) { + from = axis.logarithmic.log2lin(from); + to = axis.logarithmic.log2lin(to); + value = axis.logarithmic.log2lin(value); } // Set the presentational attributes if (!axis.chart.styledMode) { diff --git a/js/parts/Series.js b/js/parts/Series.js index efa27aee6ca..28688242bb5 100644 --- a/js/parts/Series.js +++ b/js/parts/Series.js @@ -3512,7 +3512,7 @@ null, processedXData = series.xData, processedYData = series.yData, dataLength = processedXData.length, croppedData, cropStart = 0, cropped, distance, closestPointRange, xAxis = series.xAxis, i, // loop variable options = series.options, cropThreshold = options.cropThreshold, getExtremesFromAll = series.getExtremesFromAll || options.getExtremesFromAll, // #4599 - isCartesian = series.isCartesian, xExtremes, val2lin = xAxis && xAxis.val2lin, isLog = xAxis && xAxis.isLog, throwOnUnsorted = series.requireSorting, min, max; + isCartesian = series.isCartesian, xExtremes, val2lin = xAxis && xAxis.val2lin, isLog = !!(xAxis && xAxis.logarithmic), throwOnUnsorted = series.requireSorting, min, max; // If the series data or axes haven't changed, don't go through // this. Return false to pass the message on to override methods // like in data grouping. diff --git a/js/parts/StockChart.js b/js/parts/StockChart.js index a60a068eeb6..5b6ee405d9b 100644 --- a/js/parts/StockChart.js +++ b/js/parts/StockChart.js @@ -431,8 +431,9 @@ addEvent(Axis, 'afterDrawCrosshair', function (event) { crossLabel = this.crossLabel, // the svgElement posx, posy, crossBox, formatOption = options.format, formatFormat = '', limit, align, tickInside = this.options.tickPosition === 'inside', snap = this.crosshair.snap !== false, value, offset = 0, // Use last available event (#5287) - e = event.e || (this.cross && this.cross.e), point = event.point, lin2log = this.lin2log, min, max; - if (this.isLog) { + e = event.e || (this.cross && this.cross.e), point = event.point, min, max; + if (this.logarithmic) { + var lin2log = this.logarithmic.lin2log; min = lin2log(this.min); max = lin2log(this.max); } diff --git a/js/parts/Tick.js b/js/parts/Tick.js index 13058a48a24..422fe3426a5 100644 --- a/js/parts/Tick.js +++ b/js/parts/Tick.js @@ -138,7 +138,7 @@ var Tick = /** @class */ (function () { isLast: isLast, dateTimeLabelFormat: dateTimeLabelFormat, tickPositionInfo: tickPositionInfo, - value: axis.isLog ? correctFloat(axis.lin2log(value)) : value, + value: axis.logarithmic ? correctFloat(axis.logarithmic.lin2log(value)) : value, pos: pos }; str = axis.labelFormatter.call(tick.formatCtx, this.formatCtx); diff --git a/ts/modules/boost/wgl-renderer.ts b/ts/modules/boost/wgl-renderer.ts index a26ffb858cb..4d141a132f1 100644 --- a/ts/modules/boost/wgl-renderer.ts +++ b/ts/modules/boost/wgl-renderer.ts @@ -1100,7 +1100,7 @@ function GLRenderer( shader.setUniform('xAxisLen', axis.len); shader.setUniform('xAxisPos', axis.pos); shader.setUniform('xAxisCVSCoord', (!axis.horiz) as any); - shader.setUniform('xAxisIsLog', axis.isLog as any); + shader.setUniform('xAxisIsLog', (!!axis.logarithmic) as any); shader.setUniform('xAxisReversed', (!!axis.reversed) as any); } @@ -1121,7 +1121,7 @@ function GLRenderer( shader.setUniform('yAxisLen', axis.len); shader.setUniform('yAxisPos', axis.pos); shader.setUniform('yAxisCVSCoord', (!axis.horiz) as any); - shader.setUniform('yAxisIsLog', axis.isLog as any); + shader.setUniform('yAxisIsLog', (!!axis.logarithmic) as any); shader.setUniform('yAxisReversed', (!!axis.reversed) as any); } diff --git a/ts/modules/solid-gauge.src.ts b/ts/modules/solid-gauge.src.ts index 10c10224262..0137ab198bc 100644 --- a/ts/modules/solid-gauge.src.ts +++ b/ts/modules/solid-gauge.src.ts @@ -259,7 +259,7 @@ colorAxisMethods = { } else { - if (this.isLog) { + if (this.logarithmic) { value = this.val2lin(value); } pos = 1 - ((this.max - value) / (this.max - this.min)); diff --git a/ts/parts-3d/Series.ts b/ts/parts-3d/Series.ts index f9ac09f4ae5..25a1ca1d431 100644 --- a/ts/parts-3d/Series.ts +++ b/ts/parts-3d/Series.ts @@ -65,7 +65,7 @@ H.Series.prototype.translate3dPoints = function (): void { rawPoint = series.data[i]; if (zAxis && zAxis.translate) { - zValue = zAxis.isLog && zAxis.val2lin ? + zValue = zAxis.logarithmic && zAxis.val2lin ? zAxis.val2lin(rawPoint.z as any) : rawPoint.z; // #4562 rawPoint.plotZ = zAxis.translate(zValue as any); diff --git a/ts/parts-map/ColorAxis.ts b/ts/parts-map/ColorAxis.ts index fb38bc09230..329a1814d3d 100644 --- a/ts/parts-map/ColorAxis.ts +++ b/ts/parts-map/ColorAxis.ts @@ -892,7 +892,7 @@ extend(ColorAxis.prototype, { this: Highcharts.ColorAxis, value: number ): number { - if (this.isLog) { + if (this.logarithmic) { value = this.val2lin(value); } return 1 - ( diff --git a/ts/parts-more/BubbleSeries.ts b/ts/parts-more/BubbleSeries.ts index 8671d82518f..9b802f2164e 100644 --- a/ts/parts-more/BubbleSeries.ts +++ b/ts/parts-more/BubbleSeries.ts @@ -725,7 +725,7 @@ Axis.prototype.beforePadding = function (this: Highcharts.Axis): void { }); // Apply the padding to the min and max properties - if (activeSeries.length && range > 0 && !this.isLog) { + if (activeSeries.length && range > 0 && !this.logarithmic) { pxMax -= axisLength; transA *= ( axisLength + diff --git a/ts/parts/Axis.ts b/ts/parts/Axis.ts index aa273afa9c5..c2cf80b41d2 100644 --- a/ts/parts/Axis.ts +++ b/ts/parts/Axis.ts @@ -224,7 +224,8 @@ declare global { isX?: boolean; labels?: XAxisLabelsOptions; left?: (number|string); - linearToLogConverter?: undefined; + /** @deprecated */ + linearToLogConverter?: (num: number) => number; lineColor?: (ColorString|GradientColorObject|PatternObject); lineWidth?: number; linkedTo?: number; @@ -356,7 +357,6 @@ declare global { public isDirty?: boolean; public isHidden?: boolean; public isLinked: boolean; - public isLog: boolean; public isOrdinal?: boolean; public isRadial?: boolean; public isXAxis?: boolean; @@ -3821,7 +3821,6 @@ class Axis implements AxisComposition { public isDatetimeAxis: boolean = void 0 as any; public isDirty?: boolean; public isLinked: boolean = void 0 as any; - public isLog: boolean = void 0 as any; public isOrdinal?: boolean; public isRadial?: boolean; public isXAxis?: boolean; @@ -4047,9 +4046,8 @@ class Axis implements AxisComposition { axis.plotLinesAndBandsGroups = {}; // Shorthand types - axis.isLog = type === 'logarithmic'; axis.isDatetimeAxis = isDatetimeAxis; - axis.positiveValuesOnly = axis.isLog && !(axis as any).allowNegativeLog; + axis.positiveValuesOnly = !!(axis.logarithmic && !(axis as any).allowNegativeLog); // Flag, if axis is linked to another axis axis.isLinked = defined(options.linkedTo); @@ -4227,7 +4225,7 @@ class Axis implements AxisComposition { // make sure the same symbol is added for all labels on a linear // axis - numericSymbolDetector = axis.isLog ? + numericSymbolDetector = axis.logarithmic ? Math.abs(value) : axis.tickInterval; const chart = this.chart; @@ -4452,7 +4450,7 @@ class Axis implements AxisComposition { doPostTranslate = ( axis.isOrdinal || axis.isBroken || - (axis.isLog && handleLog) + (axis.logarithmic && handleLog) ) && axis.lin2val; if (!localA) { @@ -4769,7 +4767,7 @@ class Axis implements AxisComposition { // long running script. So we don't draw them. if (range && range / minorTickInterval < axis.len / 3) { // #3875 - if (axis.isLog) { + if (axis.logarithmic) { // For each interval in the major ticks, compute the minor ticks // separately. this.paddedTicks.forEach(function ( @@ -4853,7 +4851,7 @@ class Axis implements AxisComposition { if ( axis.isXAxis && typeof axis.minRange === 'undefined' && - !axis.isLog + !axis.logarithmic ) { if (defined(options.min) || defined(options.max)) { @@ -4900,8 +4898,8 @@ class Axis implements AxisComposition { ]; // If space is available, stay within the data range if (spaceAvailable) { - minArgs[2] = axis.isLog ? - axis.log2lin(axis.dataMin as any) : + minArgs[2] = axis.logarithmic ? + axis.logarithmic.log2lin(axis.dataMin as any) : axis.dataMin; } min = arrayMax(minArgs); @@ -4912,8 +4910,8 @@ class Axis implements AxisComposition { ]; // If space is availabe, stay within the data range if (spaceAvailable) { - maxArgs[2] = axis.isLog ? - axis.log2lin(axis.dataMax as any) : + maxArgs[2] = axis.logarithmic ? + axis.logarithmic.log2lin(axis.dataMax as any) : axis.dataMax; } @@ -5225,7 +5223,6 @@ class Axis implements AxisComposition { var axis: Highcharts.Axis = this as any, chart = axis.chart, options = axis.options, - isLog = axis.isLog, isDatetimeAxis = axis.isDatetimeAxis, isXAxis = axis.isXAxis, isLinked = axis.isLinked, @@ -5290,7 +5287,7 @@ class Axis implements AxisComposition { } - if (isLog) { + if (axis.logarithmic) { if ( axis.positiveValuesOnly && !secondPass && @@ -5479,7 +5476,7 @@ class Axis implements AxisComposition { } // for linear axes, get magnitude and normalize the interval - if (!isDatetimeAxis && !isLog && !tickIntervalOption) { + if (!isDatetimeAxis && !axis.logarithmic && !tickIntervalOption) { axis.tickInterval = normalizeTickInterval( axis.tickInterval, null as any, @@ -5603,7 +5600,7 @@ class Axis implements AxisComposition { this.closestPointRange, true ); - } else if (this.isLog && axis.logarithmic) { + } else if (axis.logarithmic) { tickPositions = axis.logarithmic.getLogTickPositions( this.tickInterval, this.min as any, @@ -5735,10 +5732,11 @@ class Axis implements AxisComposition { * True if there are other axes. */ public alignToOthers(): (boolean|undefined) { - var others = // Whether there is another axis to pair with this one + var axis: Highcharts.Axis = this as any, + others = // Whether there is another axis to pair with this one {} as Highcharts.AxisOptions, hasOther, - options = this.options; + options = axis.options; if ( // Only if alignTicks is true @@ -5751,7 +5749,7 @@ class Axis implements AxisComposition { // Don't try to align ticks on a log axis, they are not evenly // spaced (#6021) - !this.isLog + !axis.logarithmic ) { (this.chart as any)[this.coll].forEach(function ( axis: Highcharts.Axis @@ -5786,7 +5784,8 @@ class Axis implements AxisComposition { * @function Highcharts.Axis#getTickAmount */ public getTickAmount(): void { - var options = this.options, + var axis: Highcharts.Axis = this as any, + options = this.options, tickAmount = options.tickAmount, tickPixelInterval = options.tickPixelInterval; @@ -5794,7 +5793,7 @@ class Axis implements AxisComposition { !defined(options.tickInterval) && this.len < (tickPixelInterval as any) && !this.isRadial && - !this.isLog && + !axis.logarithmic && options.startOnTick && options.endOnTick ) { @@ -6189,15 +6188,14 @@ class Axis implements AxisComposition { * An object containing extremes information. */ public getExtremes(): Highcharts.ExtremesObject { - var axis: Highcharts.Axis = this as any, - isLog = axis.isLog; + var axis: Highcharts.Axis = this as any; return { - min: isLog ? - correctFloat(axis.lin2log(axis.min as any)) : + min: axis.logarithmic ? + correctFloat(axis.logarithmic.lin2log(axis.min as any)) : axis.min as any, - max: isLog ? - correctFloat(axis.lin2log(axis.max as any)) : + max: axis.logarithmic ? + correctFloat(axis.logarithmic.lin2log(axis.max as any)) : axis.max as any, dataMin: axis.dataMin as any, dataMax: axis.dataMax as any, @@ -6221,9 +6219,8 @@ class Axis implements AxisComposition { */ public getThreshold(threshold: number): (number|undefined) { var axis: Highcharts.Axis = this as any, - isLog = axis.isLog, - realMin = isLog ? axis.lin2log(axis.min as any) : axis.min as any, - realMax = isLog ? axis.lin2log(axis.max as any) : axis.max as any; + realMin = axis.logarithmic ? axis.logarithmic.lin2log(axis.min as any) : axis.min as any, + realMax = axis.logarithmic ? axis.logarithmic.lin2log(axis.max as any) : axis.max as any; if (threshold === null || threshold === -Infinity) { threshold = realMin; @@ -7197,7 +7194,6 @@ class Axis implements AxisComposition { chart = axis.chart, renderer = chart.renderer, options = axis.options, - isLog = axis.isLog, isLinked = axis.isLinked, tickPositions = axis.tickPositions, axisTitle = axis.axisTitle, @@ -7283,8 +7279,8 @@ class Axis implements AxisComposition { } from = pos + tickmarkOffset; // #949 alternateBands[pos].options = { - from: isLog ? axis.lin2log(from) : from, - to: isLog ? axis.lin2log(to) : to, + from: axis.logarithmic ? axis.logarithmic.lin2log(from) : from, + to: axis.logarithmic ? axis.logarithmic.lin2log(to) : to, color: alternateGridColor }; alternateBands[pos].render(); diff --git a/ts/parts/LogarithmicAxis.ts b/ts/parts/LogarithmicAxis.ts index 4c78bac07ae..79f5fe3f631 100644 --- a/ts/parts/LogarithmicAxis.ts +++ b/ts/parts/LogarithmicAxis.ts @@ -237,9 +237,15 @@ class LogarithmicAxis { /* eslint-disable no-invalid-this */ - addEvent(AxisClass, 'init', function (): void { - const axis = this as LogarithmicAxis; - axis.logarithmic = new LogarithmicAxisAdditions(axis); + addEvent(AxisClass, 'init', function (e: { userOptions: Axis['options'] }): void { + const axis = this; + const options = e.userOptions; + + if (options.type === 'logarithmic') { + axis.logarithmic = new LogarithmicAxisAdditions(axis as LogarithmicAxis); + } else { + axis.logarithmic = void 0; + } }); addEvent(AxisClass, 'afterInit', function (): void { @@ -247,7 +253,7 @@ class LogarithmicAxis { const options = axis.options; // extend logarithmic axis axis.lin2log = options.linearToLogConverter || axis.lin2log; - if (axis.isLog) { + if (axis.logarithmic) { axis.val2lin = axis.log2lin; axis.lin2val = axis.lin2log; } diff --git a/ts/parts/PlotLineOrBand.ts b/ts/parts/PlotLineOrBand.ts index fb208b2798b..55d5edd612e 100644 --- a/ts/parts/PlotLineOrBand.ts +++ b/ts/parts/PlotLineOrBand.ts @@ -240,10 +240,10 @@ class PlotLineOrBand { group; // logarithmic conversion - if (axis.isLog) { - from = axis.log2lin(from); - to = axis.log2lin(to); - value = axis.log2lin(value); + if (axis.logarithmic) { + from = axis.logarithmic.log2lin(from); + to = axis.logarithmic.log2lin(to); + value = axis.logarithmic.log2lin(value); } // Set the presentational attributes diff --git a/ts/parts/Series.ts b/ts/parts/Series.ts index 1cf7d5d8066..ecdfd98028d 100644 --- a/ts/parts/Series.ts +++ b/ts/parts/Series.ts @@ -4571,7 +4571,7 @@ H.Series = seriesType( isCartesian = series.isCartesian, xExtremes, val2lin = xAxis && xAxis.val2lin, - isLog = xAxis && xAxis.isLog, + isLog = !!(xAxis && xAxis.logarithmic), throwOnUnsorted = series.requireSorting, min, max; diff --git a/ts/parts/StockChart.ts b/ts/parts/StockChart.ts index c2fce30ee16..d99182883c4 100644 --- a/ts/parts/StockChart.ts +++ b/ts/parts/StockChart.ts @@ -667,11 +667,11 @@ addEvent(Axis, 'afterDrawCrosshair', function ( // Use last available event (#5287) e = event.e || (this.cross && this.cross.e), point = event.point, - lin2log = this.lin2log, min, max; - if (this.isLog) { + if (this.logarithmic) { + const lin2log = this.logarithmic.lin2log; min = lin2log(this.min as any); max = lin2log(this.max as any); } else { diff --git a/ts/parts/Tick.ts b/ts/parts/Tick.ts index ff680790482..0d98e341ad4 100644 --- a/ts/parts/Tick.ts +++ b/ts/parts/Tick.ts @@ -351,7 +351,7 @@ class Tick { isLast: isLast, dateTimeLabelFormat: dateTimeLabelFormat as any, tickPositionInfo: tickPositionInfo, - value: axis.isLog ? correctFloat(axis.lin2log(value)) : value, + value: axis.logarithmic ? correctFloat(axis.logarithmic.lin2log(value)) : value, pos: pos }; str = (axis.labelFormatter as any).call(tick.formatCtx, this.formatCtx); From dd777d1c1ced6415f460fc27bc169bb828d3ab47 Mon Sep 17 00:00:00 2001 From: bre1470 <40056287+bre1470@users.noreply.github.com> Date: Thu, 26 Mar 2020 11:23:30 +0100 Subject: [PATCH 04/10] Fixed custom logarithmic extremes. --- js/parts-map/ColorAxis.js | 2 +- js/parts/LogarithmicAxis.js | 18 ++++++++++++++++-- js/parts/StockChart.js | 15 +++++---------- js/parts/Utilities.js | 4 +++- ts/parts-map/ColorAxis.ts | 2 +- ts/parts/LogarithmicAxis.ts | 23 +++++++++++++++++++++-- ts/parts/StockChart.ts | 15 ++++++--------- 7 files changed, 53 insertions(+), 26 deletions(-) diff --git a/js/parts-map/ColorAxis.js b/js/parts-map/ColorAxis.js index e1c8f727e9e..eb604bbd655 100644 --- a/js/parts-map/ColorAxis.js +++ b/js/parts-map/ColorAxis.js @@ -637,7 +637,7 @@ extend(ColorAxis.prototype, { */ normalizedValue: function (value) { if (this.logarithmic) { - value = this.val2lin(value); + value = this.logarithmic.log2lin(value); } return 1 - ((this.max - value) / ((this.max - this.min) || 1)); diff --git a/js/parts/LogarithmicAxis.js b/js/parts/LogarithmicAxis.js index 7760fe8a855..4c0656a4f55 100644 --- a/js/parts/LogarithmicAxis.js +++ b/js/parts/LogarithmicAxis.js @@ -32,6 +32,10 @@ var LogarithmicAxisAdditions = /** @class */ (function () { * Functions * * */ + LogarithmicAxisAdditions.prototype.destroy = function () { + this.axis = void 0; + this.minorAutoInterval = void 0; + }; /** * Set the tick positions of a logarithmic axis. */ @@ -109,6 +113,11 @@ var LogarithmicAxisAdditions = /** @class */ (function () { return positions; }; LogarithmicAxisAdditions.prototype.lin2log = function (num) { + var axis = this.axis; + var lin2log = axis.options.linearToLogConverter; + if (typeof lin2log === 'function') { + return lin2log.apply(axis, arguments); + } return Math.pow(10, num); }; LogarithmicAxisAdditions.prototype.log2lin = function (num) { @@ -136,6 +145,11 @@ var LogarithmicAxis = /** @class */ (function () { * @return {number} */ axisProto.lin2log = function (num) { + var axis = this; + var lin2log = axis.options.linearToLogConverter; + if (typeof lin2log === 'function') { + return lin2log.apply(axis, arguments); + } return Math.pow(10, num); }; /** @@ -157,7 +171,8 @@ var LogarithmicAxis = /** @class */ (function () { if (options.type === 'logarithmic') { axis.logarithmic = new LogarithmicAxisAdditions(axis); } - else { + else if (axis.logarithmic) { + axis.logarithmic.destroy(); axis.logarithmic = void 0; } }); @@ -165,7 +180,6 @@ var LogarithmicAxis = /** @class */ (function () { var axis = this; var options = axis.options; // extend logarithmic axis - axis.lin2log = options.linearToLogConverter || axis.lin2log; if (axis.logarithmic) { axis.val2lin = axis.log2lin; axis.lin2val = axis.lin2log; diff --git a/js/parts/StockChart.js b/js/parts/StockChart.js index 5b6ee405d9b..60f8a06638a 100644 --- a/js/parts/StockChart.js +++ b/js/parts/StockChart.js @@ -429,17 +429,12 @@ addEvent(Axis, 'afterDrawCrosshair', function (event) { left = this.left, // left position top = this.top, // top position crossLabel = this.crossLabel, // the svgElement - posx, posy, crossBox, formatOption = options.format, formatFormat = '', limit, align, tickInside = this.options.tickPosition === 'inside', snap = this.crosshair.snap !== false, value, offset = 0, + posx, posy, crossBox, formatOption = options.format, formatFormat = '', limit, logarithmic = this.logarithmic, align, tickInside = this.options.tickPosition === 'inside', snap = this.crosshair.snap !== false, value, offset = 0, // Use last available event (#5287) - e = event.e || (this.cross && this.cross.e), point = event.point, min, max; - if (this.logarithmic) { - var lin2log = this.logarithmic.lin2log; - min = lin2log(this.min); - max = lin2log(this.max); - } - else { - min = this.min; - max = this.max; + e = event.e || (this.cross && this.cross.e), point = event.point, min = this.min, max = this.max; + if (logarithmic) { + min = logarithmic.lin2log(min); + max = logarithmic.lin2log(max); } align = (horiz ? 'center' : opposite ? (this.labelAlign === 'right' ? 'right' : 'left') : diff --git a/js/parts/Utilities.js b/js/parts/Utilities.js index 6682474516a..a939facec0d 100644 --- a/js/parts/Utilities.js +++ b/js/parts/Utilities.js @@ -1596,7 +1596,9 @@ var discardElement = H.discardElement = function discardElement(element) { * The corrected float number. */ var correctFloat = H.correctFloat = function correctFloat(num, prec) { - return parseFloat(num.toPrecision(prec || 14)); + var v = parseFloat(num.toPrecision(prec || 14)); + console.log(num, v); + return v; }; /** * Set the global animation to either a given value, or fall back to the given diff --git a/ts/parts-map/ColorAxis.ts b/ts/parts-map/ColorAxis.ts index 329a1814d3d..efe82d5c0b8 100644 --- a/ts/parts-map/ColorAxis.ts +++ b/ts/parts-map/ColorAxis.ts @@ -893,7 +893,7 @@ extend(ColorAxis.prototype, { value: number ): number { if (this.logarithmic) { - value = this.val2lin(value); + value = this.logarithmic.log2lin(value); } return 1 - ( ((this.max as any) - value) / diff --git a/ts/parts/LogarithmicAxis.ts b/ts/parts/LogarithmicAxis.ts index 79f5fe3f631..11b10cf3e33 100644 --- a/ts/parts/LogarithmicAxis.ts +++ b/ts/parts/LogarithmicAxis.ts @@ -69,6 +69,11 @@ class LogarithmicAxisAdditions { * * */ + public destroy(): void { + this.axis = void 0 as any; + this.minorAutoInterval = void 0; + } + /** * Set the tick positions of a logarithmic axis. */ @@ -189,6 +194,13 @@ class LogarithmicAxisAdditions { } public lin2log(num: number): number { + const axis = this.axis; + const lin2log = axis.options.linearToLogConverter; + + if (typeof lin2log === 'function') { + return lin2log.apply(axis, arguments); + } + return Math.pow(10, num); } @@ -219,6 +231,13 @@ class LogarithmicAxis { * @return {number} */ axisProto.lin2log = function (this: Highcharts.Axis, num: number): number { + const axis = this; + const lin2log = axis.options.linearToLogConverter; + + if (typeof lin2log === 'function') { + return lin2log.apply(axis, arguments); + } + return Math.pow(10, num); }; @@ -243,7 +262,8 @@ class LogarithmicAxis { if (options.type === 'logarithmic') { axis.logarithmic = new LogarithmicAxisAdditions(axis as LogarithmicAxis); - } else { + } else if (axis.logarithmic) { + axis.logarithmic.destroy(); axis.logarithmic = void 0; } }); @@ -252,7 +272,6 @@ class LogarithmicAxis { const axis = this as LogarithmicAxis; const options = axis.options; // extend logarithmic axis - axis.lin2log = options.linearToLogConverter || axis.lin2log; if (axis.logarithmic) { axis.val2lin = axis.log2lin; axis.lin2val = axis.lin2log; diff --git a/ts/parts/StockChart.ts b/ts/parts/StockChart.ts index d99182883c4..3b2762a310e 100644 --- a/ts/parts/StockChart.ts +++ b/ts/parts/StockChart.ts @@ -659,6 +659,7 @@ addEvent(Axis, 'afterDrawCrosshair', function ( formatOption = options.format, formatFormat = '', limit, + logarithmic = this.logarithmic, align, tickInside = this.options.tickPosition === 'inside', snap = (this.crosshair as any).snap !== false, @@ -667,16 +668,12 @@ addEvent(Axis, 'afterDrawCrosshair', function ( // Use last available event (#5287) e = event.e || (this.cross && this.cross.e), point = event.point, - min, - max; - - if (this.logarithmic) { - const lin2log = this.logarithmic.lin2log; - min = lin2log(this.min as any); - max = lin2log(this.max as any); - } else { - min = this.min; + min = this.min, max = this.max; + + if (logarithmic) { + min = logarithmic.lin2log(min as any); + max = logarithmic.lin2log(max as any); } align = (horiz ? 'center' : opposite ? From c87555a1f4e7f64ec51fb4261f66bb790bfb17ff Mon Sep 17 00:00:00 2001 From: bre1470 <40056287+bre1470@users.noreply.github.com> Date: Thu, 26 Mar 2020 11:30:00 +0100 Subject: [PATCH 05/10] Fixed custom logarithmic extremes. --- js/parts/Utilities.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/js/parts/Utilities.js b/js/parts/Utilities.js index a939facec0d..6682474516a 100644 --- a/js/parts/Utilities.js +++ b/js/parts/Utilities.js @@ -1596,9 +1596,7 @@ var discardElement = H.discardElement = function discardElement(element) { * The corrected float number. */ var correctFloat = H.correctFloat = function correctFloat(num, prec) { - var v = parseFloat(num.toPrecision(prec || 14)); - console.log(num, v); - return v; + return parseFloat(num.toPrecision(prec || 14)); }; /** * Set the global animation to either a given value, or fall back to the given From 74a6c3b7ad3e0fd9366f27c5a4c78669dc6db06b Mon Sep 17 00:00:00 2001 From: bre1470 <40056287+bre1470@users.noreply.github.com> Date: Thu, 26 Mar 2020 12:20:16 +0100 Subject: [PATCH 06/10] Restored usage of deprecated lin/log functions for compatibility. --- js/parts-map/ColorAxis.js | 2 +- js/parts/Axis.js | 16 ++++++++-------- js/parts/LogarithmicAxis.js | 1 - js/parts/PlotLineOrBand.js | 6 +++--- js/parts/StockChart.js | 8 ++++---- js/parts/Tick.js | 2 +- ts/parts-map/ColorAxis.ts | 2 +- ts/parts/Axis.ts | 19 ++++++++++--------- ts/parts/LogarithmicAxis.ts | 3 ++- ts/parts/PlotLineOrBand.ts | 6 +++--- ts/parts/StockChart.ts | 7 +++---- ts/parts/Tick.ts | 2 +- 12 files changed, 37 insertions(+), 37 deletions(-) diff --git a/js/parts-map/ColorAxis.js b/js/parts-map/ColorAxis.js index eb604bbd655..3526fcaa2df 100644 --- a/js/parts-map/ColorAxis.js +++ b/js/parts-map/ColorAxis.js @@ -637,7 +637,7 @@ extend(ColorAxis.prototype, { */ normalizedValue: function (value) { if (this.logarithmic) { - value = this.logarithmic.log2lin(value); + value = this.log2lin(value); } return 1 - ((this.max - value) / ((this.max - this.min) || 1)); diff --git a/js/parts/Axis.js b/js/parts/Axis.js index 06823c74800..87192dd03f7 100644 --- a/js/parts/Axis.js +++ b/js/parts/Axis.js @@ -425,7 +425,7 @@ var Axis = /** @class */ (function () { axis.plotLinesAndBandsGroups = {}; // Shorthand types axis.isDatetimeAxis = isDatetimeAxis; - axis.positiveValuesOnly = !!(axis.logarithmic && !axis.allowNegativeLog); + axis.positiveValuesOnly = !!(axis.logarithmic && !options.allowNegativeLog); // Flag, if axis is linked to another axis axis.isLinked = defined(options.linkedTo); /** @@ -1033,7 +1033,7 @@ var Axis = /** @class */ (function () { // If space is available, stay within the data range if (spaceAvailable) { minArgs[2] = axis.logarithmic ? - axis.logarithmic.log2lin(axis.dataMin) : + axis.log2lin(axis.dataMin) : axis.dataMin; } min = arrayMax(minArgs); @@ -1044,7 +1044,7 @@ var Axis = /** @class */ (function () { // If space is availabe, stay within the data range if (spaceAvailable) { maxArgs[2] = axis.logarithmic ? - axis.logarithmic.log2lin(axis.dataMax) : + axis.log2lin(axis.dataMax) : axis.dataMax; } max = arrayMin(maxArgs); @@ -1961,10 +1961,10 @@ var Axis = /** @class */ (function () { var axis = this; return { min: axis.logarithmic ? - correctFloat(axis.logarithmic.lin2log(axis.min)) : + correctFloat(axis.lin2log(axis.min)) : axis.min, max: axis.logarithmic ? - correctFloat(axis.logarithmic.lin2log(axis.max)) : + correctFloat(axis.lin2log(axis.max)) : axis.max, dataMin: axis.dataMin, dataMax: axis.dataMax, @@ -1986,7 +1986,7 @@ var Axis = /** @class */ (function () { * stay within the axis bounds. */ Axis.prototype.getThreshold = function (threshold) { - var axis = this, realMin = axis.logarithmic ? axis.logarithmic.lin2log(axis.min) : axis.min, realMax = axis.logarithmic ? axis.logarithmic.lin2log(axis.max) : axis.max; + var axis = this, realMin = axis.logarithmic ? axis.lin2log(axis.min) : axis.min, realMax = axis.logarithmic ? axis.lin2log(axis.max) : axis.max; if (threshold === null || threshold === -Infinity) { threshold = realMin; } @@ -2716,8 +2716,8 @@ var Axis = /** @class */ (function () { } from = pos + tickmarkOffset; // #949 alternateBands[pos].options = { - from: axis.logarithmic ? axis.logarithmic.lin2log(from) : from, - to: axis.logarithmic ? axis.logarithmic.lin2log(to) : to, + from: axis.logarithmic ? axis.lin2log(from) : from, + to: axis.logarithmic ? axis.lin2log(to) : to, color: alternateGridColor }; alternateBands[pos].render(); diff --git a/js/parts/LogarithmicAxis.js b/js/parts/LogarithmicAxis.js index 4c0656a4f55..6894d2f9786 100644 --- a/js/parts/LogarithmicAxis.js +++ b/js/parts/LogarithmicAxis.js @@ -178,7 +178,6 @@ var LogarithmicAxis = /** @class */ (function () { }); addEvent(AxisClass, 'afterInit', function () { var axis = this; - var options = axis.options; // extend logarithmic axis if (axis.logarithmic) { axis.val2lin = axis.log2lin; diff --git a/js/parts/PlotLineOrBand.js b/js/parts/PlotLineOrBand.js index 6fa1af1dc62..ce79cbf8885 100644 --- a/js/parts/PlotLineOrBand.js +++ b/js/parts/PlotLineOrBand.js @@ -67,9 +67,9 @@ var PlotLineOrBand = /** @class */ (function () { }, groupAttribs = {}, renderer = axis.chart.renderer, groupName = isBand ? 'bands' : 'lines', group; // logarithmic conversion if (axis.logarithmic) { - from = axis.logarithmic.log2lin(from); - to = axis.logarithmic.log2lin(to); - value = axis.logarithmic.log2lin(value); + from = axis.log2lin(from); + to = axis.log2lin(to); + value = axis.log2lin(value); } // Set the presentational attributes if (!axis.chart.styledMode) { diff --git a/js/parts/StockChart.js b/js/parts/StockChart.js index 60f8a06638a..be0119988db 100644 --- a/js/parts/StockChart.js +++ b/js/parts/StockChart.js @@ -429,12 +429,12 @@ addEvent(Axis, 'afterDrawCrosshair', function (event) { left = this.left, // left position top = this.top, // top position crossLabel = this.crossLabel, // the svgElement - posx, posy, crossBox, formatOption = options.format, formatFormat = '', limit, logarithmic = this.logarithmic, align, tickInside = this.options.tickPosition === 'inside', snap = this.crosshair.snap !== false, value, offset = 0, + posx, posy, crossBox, formatOption = options.format, formatFormat = '', limit, align, tickInside = this.options.tickPosition === 'inside', snap = this.crosshair.snap !== false, value, offset = 0, // Use last available event (#5287) e = event.e || (this.cross && this.cross.e), point = event.point, min = this.min, max = this.max; - if (logarithmic) { - min = logarithmic.lin2log(min); - max = logarithmic.lin2log(max); + if (this.logarithmic) { + min = this.lin2log(min); + max = this.lin2log(max); } align = (horiz ? 'center' : opposite ? (this.labelAlign === 'right' ? 'right' : 'left') : diff --git a/js/parts/Tick.js b/js/parts/Tick.js index 422fe3426a5..bd49e0edd6e 100644 --- a/js/parts/Tick.js +++ b/js/parts/Tick.js @@ -138,7 +138,7 @@ var Tick = /** @class */ (function () { isLast: isLast, dateTimeLabelFormat: dateTimeLabelFormat, tickPositionInfo: tickPositionInfo, - value: axis.logarithmic ? correctFloat(axis.logarithmic.lin2log(value)) : value, + value: axis.logarithmic ? correctFloat(axis.lin2log(value)) : value, pos: pos }; str = axis.labelFormatter.call(tick.formatCtx, this.formatCtx); diff --git a/ts/parts-map/ColorAxis.ts b/ts/parts-map/ColorAxis.ts index efe82d5c0b8..c671a718302 100644 --- a/ts/parts-map/ColorAxis.ts +++ b/ts/parts-map/ColorAxis.ts @@ -893,7 +893,7 @@ extend(ColorAxis.prototype, { value: number ): number { if (this.logarithmic) { - value = this.logarithmic.log2lin(value); + value = this.log2lin(value); } return 1 - ( ((this.max as any) - value) / diff --git a/ts/parts/Axis.ts b/ts/parts/Axis.ts index c2cf80b41d2..bf71fc43ba2 100644 --- a/ts/parts/Axis.ts +++ b/ts/parts/Axis.ts @@ -203,6 +203,7 @@ declare global { accessibility?: XAxisAccessibilityOptions; alignTicks?: boolean; allowDecimals?: boolean; + allowNegativeLog?: boolean; alternateGridColor?: ( ColorString|GradientColorObject|PatternObject ); @@ -4047,7 +4048,7 @@ class Axis implements AxisComposition { // Shorthand types axis.isDatetimeAxis = isDatetimeAxis; - axis.positiveValuesOnly = !!(axis.logarithmic && !(axis as any).allowNegativeLog); + axis.positiveValuesOnly = !!(axis.logarithmic && !options.allowNegativeLog); // Flag, if axis is linked to another axis axis.isLinked = defined(options.linkedTo); @@ -4899,7 +4900,7 @@ class Axis implements AxisComposition { // If space is available, stay within the data range if (spaceAvailable) { minArgs[2] = axis.logarithmic ? - axis.logarithmic.log2lin(axis.dataMin as any) : + axis.log2lin(axis.dataMin as any) : axis.dataMin; } min = arrayMax(minArgs); @@ -4911,7 +4912,7 @@ class Axis implements AxisComposition { // If space is availabe, stay within the data range if (spaceAvailable) { maxArgs[2] = axis.logarithmic ? - axis.logarithmic.log2lin(axis.dataMax as any) : + axis.log2lin(axis.dataMax as any) : axis.dataMax; } @@ -6192,10 +6193,10 @@ class Axis implements AxisComposition { return { min: axis.logarithmic ? - correctFloat(axis.logarithmic.lin2log(axis.min as any)) : + correctFloat(axis.lin2log(axis.min as any)) : axis.min as any, max: axis.logarithmic ? - correctFloat(axis.logarithmic.lin2log(axis.max as any)) : + correctFloat(axis.lin2log(axis.max as any)) : axis.max as any, dataMin: axis.dataMin as any, dataMax: axis.dataMax as any, @@ -6219,8 +6220,8 @@ class Axis implements AxisComposition { */ public getThreshold(threshold: number): (number|undefined) { var axis: Highcharts.Axis = this as any, - realMin = axis.logarithmic ? axis.logarithmic.lin2log(axis.min as any) : axis.min as any, - realMax = axis.logarithmic ? axis.logarithmic.lin2log(axis.max as any) : axis.max as any; + realMin = axis.logarithmic ? axis.lin2log(axis.min as any) : axis.min as any, + realMax = axis.logarithmic ? axis.lin2log(axis.max as any) : axis.max as any; if (threshold === null || threshold === -Infinity) { threshold = realMin; @@ -7279,8 +7280,8 @@ class Axis implements AxisComposition { } from = pos + tickmarkOffset; // #949 alternateBands[pos].options = { - from: axis.logarithmic ? axis.logarithmic.lin2log(from) : from, - to: axis.logarithmic ? axis.logarithmic.lin2log(to) : to, + from: axis.logarithmic ? axis.lin2log(from) : from, + to: axis.logarithmic ? axis.lin2log(to) : to, color: alternateGridColor }; alternateBands[pos].render(); diff --git a/ts/parts/LogarithmicAxis.ts b/ts/parts/LogarithmicAxis.ts index 11b10cf3e33..5ece3cdbda7 100644 --- a/ts/parts/LogarithmicAxis.ts +++ b/ts/parts/LogarithmicAxis.ts @@ -270,7 +270,6 @@ class LogarithmicAxis { addEvent(AxisClass, 'afterInit', function (): void { const axis = this as LogarithmicAxis; - const options = axis.options; // extend logarithmic axis if (axis.logarithmic) { axis.val2lin = axis.log2lin; @@ -282,7 +281,9 @@ class LogarithmicAxis { interface LogarithmicAxis extends Axis { logarithmic: LogarithmicAxisAdditions; + /** @deprecated */ lin2log(num: number): number; + /** @deprecated */ log2lin(num: number): number; } diff --git a/ts/parts/PlotLineOrBand.ts b/ts/parts/PlotLineOrBand.ts index 55d5edd612e..8b0082b5087 100644 --- a/ts/parts/PlotLineOrBand.ts +++ b/ts/parts/PlotLineOrBand.ts @@ -241,9 +241,9 @@ class PlotLineOrBand { // logarithmic conversion if (axis.logarithmic) { - from = axis.logarithmic.log2lin(from); - to = axis.logarithmic.log2lin(to); - value = axis.logarithmic.log2lin(value); + from = axis.log2lin(from); + to = axis.log2lin(to); + value = axis.log2lin(value); } // Set the presentational attributes diff --git a/ts/parts/StockChart.ts b/ts/parts/StockChart.ts index 3b2762a310e..b0d5d6802db 100644 --- a/ts/parts/StockChart.ts +++ b/ts/parts/StockChart.ts @@ -659,7 +659,6 @@ addEvent(Axis, 'afterDrawCrosshair', function ( formatOption = options.format, formatFormat = '', limit, - logarithmic = this.logarithmic, align, tickInside = this.options.tickPosition === 'inside', snap = (this.crosshair as any).snap !== false, @@ -671,9 +670,9 @@ addEvent(Axis, 'afterDrawCrosshair', function ( min = this.min, max = this.max; - if (logarithmic) { - min = logarithmic.lin2log(min as any); - max = logarithmic.lin2log(max as any); + if (this.logarithmic) { + min = this.lin2log(min as any); + max = this.lin2log(max as any); } align = (horiz ? 'center' : opposite ? diff --git a/ts/parts/Tick.ts b/ts/parts/Tick.ts index 0d98e341ad4..3c828ec5bc3 100644 --- a/ts/parts/Tick.ts +++ b/ts/parts/Tick.ts @@ -351,7 +351,7 @@ class Tick { isLast: isLast, dateTimeLabelFormat: dateTimeLabelFormat as any, tickPositionInfo: tickPositionInfo, - value: axis.logarithmic ? correctFloat(axis.logarithmic.lin2log(value)) : value, + value: axis.logarithmic ? correctFloat(axis.lin2log(value)) : value, pos: pos }; str = (axis.labelFormatter as any).call(tick.formatCtx, this.formatCtx); From 10708afc03f766da0af311d33accc101853aed44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torstein=20H=C3=B8nsi?= Date: Thu, 26 Mar 2020 13:19:50 +0100 Subject: [PATCH 07/10] Log axis, Small refactor --- js/parts/Axis.js | 7 ++++--- ts/parts/Axis.ts | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/js/parts/Axis.js b/js/parts/Axis.js index 87192dd03f7..e78e8c1a9f5 100644 --- a/js/parts/Axis.js +++ b/js/parts/Axis.js @@ -953,12 +953,13 @@ var Axis = /** @class */ (function () { // 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 - if (axis.logarithmic) { + 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 && axis.logarithmic) { - minorTickPositions.push.apply(minorTickPositions, axis.logarithmic.getLogTickPositions(minorTickInterval, paddedTicks[i - 1], paddedTicks[i], true)); + if (i) { + minorTickPositions.push.apply(minorTickPositions, logarithmic_1.getLogTickPositions(minorTickInterval, paddedTicks[i - 1], paddedTicks[i], true)); } }); } diff --git a/ts/parts/Axis.ts b/ts/parts/Axis.ts index bf71fc43ba2..0f5ac262842 100644 --- a/ts/parts/Axis.ts +++ b/ts/parts/Axis.ts @@ -4768,7 +4768,8 @@ class Axis implements AxisComposition { // long running script. So we don't draw them. if (range && range / minorTickInterval < axis.len / 3) { // #3875 - if (axis.logarithmic) { + const logarithmic = axis.logarithmic; + if (logarithmic) { // For each interval in the major ticks, compute the minor ticks // separately. this.paddedTicks.forEach(function ( @@ -4776,10 +4777,10 @@ class Axis implements AxisComposition { i: number, paddedTicks: Array ): void { - if (i && axis.logarithmic) { + if (i) { minorTickPositions.push.apply( minorTickPositions, - axis.logarithmic.getLogTickPositions( + logarithmic.getLogTickPositions( minorTickInterval, paddedTicks[i - 1], paddedTicks[i], From 580e0ffa8092bb487d33ffe78d832aad3572f1ae Mon Sep 17 00:00:00 2001 From: bre1470 <40056287+bre1470@users.noreply.github.com> Date: Thu, 26 Mar 2020 14:29:02 +0100 Subject: [PATCH 08/10] Simplified logarithmic composition for axis. --- js/parts-map/ColorAxis.js | 2 +- js/parts/Axis.js | 35 ++++++++------- js/parts/LogarithmicAxis.js | 61 +++++++------------------ js/parts/PlotLineOrBand.js | 10 ++--- js/parts/StockChart.js | 8 ++-- js/parts/Tick.js | 4 +- ts/parts-map/ColorAxis.ts | 2 +- ts/parts/Axis.ts | 37 ++++++++------- ts/parts/LogarithmicAxis.ts | 89 ++++++++----------------------------- ts/parts/PlotLineOrBand.ts | 9 ++-- ts/parts/StockChart.ts | 7 +-- ts/parts/Tick.ts | 3 +- 12 files changed, 98 insertions(+), 169 deletions(-) diff --git a/js/parts-map/ColorAxis.js b/js/parts-map/ColorAxis.js index 3526fcaa2df..eb604bbd655 100644 --- a/js/parts-map/ColorAxis.js +++ b/js/parts-map/ColorAxis.js @@ -637,7 +637,7 @@ extend(ColorAxis.prototype, { */ normalizedValue: function (value) { if (this.logarithmic) { - value = this.log2lin(value); + value = this.logarithmic.log2lin(value); } return 1 - ((this.max - value) / ((this.max - this.min) || 1)); diff --git a/js/parts/Axis.js b/js/parts/Axis.js index e78e8c1a9f5..b150e240d81 100644 --- a/js/parts/Axis.js +++ b/js/parts/Axis.js @@ -993,11 +993,11 @@ var Axis = /** @class */ (function () { * @function Highcharts.Axis#adjustForMinRange */ Axis.prototype.adjustForMinRange = function () { - var axis = this, options = axis.options, min = axis.min, max = axis.max, zoomOffset, spaceAvailable, closestDataRange, i, distance, xData, loopLength, minArgs, maxArgs, minRange; + 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' && - !axis.logarithmic) { + !log) { if (defined(options.min) || defined(options.max)) { axis.minRange = null; // don't do this again } @@ -1034,7 +1034,7 @@ var Axis = /** @class */ (function () { // If space is available, stay within the data range if (spaceAvailable) { minArgs[2] = axis.logarithmic ? - axis.log2lin(axis.dataMin) : + axis.logarithmic.log2lin(axis.dataMin) : axis.dataMin; } min = arrayMax(minArgs); @@ -1044,8 +1044,8 @@ var Axis = /** @class */ (function () { ]; // If space is availabe, stay within the data range if (spaceAvailable) { - maxArgs[2] = axis.logarithmic ? - axis.log2lin(axis.dataMax) : + maxArgs[2] = log ? + log.log2lin(axis.dataMax) : axis.dataMax; } max = arrayMin(maxArgs); @@ -1276,7 +1276,7 @@ var Axis = /** @class */ (function () { * @fires Highcharts.Axis#event:foundExtremes */ Axis.prototype.setTickInterval = function (secondPass) { - var axis = this, chart = axis.chart, options = axis.options, isDatetimeAxis = axis.isDatetimeAxis, 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; + var axis = this, chart = axis.chart, log = axis.logarithmic, options = axis.options, isDatetimeAxis = axis.isDatetimeAxis, 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 (!isDatetimeAxis && !categories && !isLinked) { this.getTickAmount(); } @@ -1310,7 +1310,7 @@ var Axis = /** @class */ (function () { axis.min = pick(hardMin, thresholdMin, axis.dataMin); axis.max = pick(hardMax, thresholdMax, axis.dataMax); } - if (axis.logarithmic) { + if (log) { if (axis.positiveValuesOnly && !secondPass && Math.min(axis.min, pick(axis.dataMin, axis.min)) <= 0) { // #978 @@ -1320,8 +1320,8 @@ var Axis = /** @class */ (function () { // 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(axis.log2lin(axis.min), 16); - axis.max = correctFloat(axis.log2lin(axis.max), 16); + 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)) { @@ -1960,12 +1960,13 @@ var Axis = /** @class */ (function () { */ Axis.prototype.getExtremes = function () { var axis = this; + var log = axis.logarithmic; return { - min: axis.logarithmic ? - correctFloat(axis.lin2log(axis.min)) : + min: log ? + correctFloat(log.lin2log(axis.min)) : axis.min, - max: axis.logarithmic ? - correctFloat(axis.lin2log(axis.max)) : + max: log ? + correctFloat(log.lin2log(axis.max)) : axis.max, dataMin: axis.dataMin, dataMax: axis.dataMax, @@ -1987,7 +1988,7 @@ var Axis = /** @class */ (function () { * stay within the axis bounds. */ Axis.prototype.getThreshold = function (threshold) { - var axis = this, realMin = axis.logarithmic ? axis.lin2log(axis.min) : axis.min, realMax = axis.logarithmic ? axis.lin2log(axis.max) : axis.max; + 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; } @@ -2665,7 +2666,7 @@ var Axis = /** @class */ (function () { * @fires Highcharts.Axis#event:afterRender */ Axis.prototype.render = function () { - var axis = this, chart = axis.chart, 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; + 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; @@ -2717,8 +2718,8 @@ var Axis = /** @class */ (function () { } from = pos + tickmarkOffset; // #949 alternateBands[pos].options = { - from: axis.logarithmic ? axis.lin2log(from) : from, - to: axis.logarithmic ? axis.lin2log(to) : to, + from: log ? log.lin2log(from) : from, + to: log ? log.lin2log(to) : to, color: alternateGridColor }; alternateBands[pos].render(); diff --git a/js/parts/LogarithmicAxis.js b/js/parts/LogarithmicAxis.js index 6894d2f9786..58f764e95a7 100644 --- a/js/parts/LogarithmicAxis.js +++ b/js/parts/LogarithmicAxis.js @@ -73,7 +73,7 @@ var LogarithmicAxisAdditions = /** @class */ (function () { for (i = roundedMin; i < max + 1 && !break2; i++) { len = intermediate.length; for (j = 0; j < len && !break2; j++) { - pos = axis.log2lin(axis.lin2log(i) * intermediate[j]); + pos = log.log2lin(log.lin2log(i) * intermediate[j]); // #1670, lastPos is #3113 if (pos > min && (!minor || lastPos <= max) && @@ -91,7 +91,7 @@ var LogarithmicAxisAdditions = /** @class */ (function () { // example 1.01, 1.02, 1.03, 1.04. } else { - var realMin = axis.lin2log(min), realMax = axis.lin2log(max), tickIntervalOption = minor ? + var realMin = log.lin2log(min), realMax = log.lin2log(max), tickIntervalOption = minor ? axis.getMinorTickInterval() : options.tickInterval, filteredTickIntervalOption = tickIntervalOption === 'auto' ? null : @@ -101,7 +101,7 @@ var LogarithmicAxisAdditions = /** @class */ (function () { interval = pick(filteredTickIntervalOption, log.minorAutoInterval, (realMax - realMin) * tickPixelIntervalOption / (totalPixelLength || 1)); interval = normalizeTickInterval(interval, void 0, getMagnitude(interval)); - positions = axis.getLinearTickPositions(interval, realMin, realMax).map(axis.log2lin); + positions = axis.getLinearTickPositions(interval, realMin, realMax).map(log.log2lin); if (!minor) { log.minorAutoInterval = interval / 5; } @@ -113,11 +113,6 @@ var LogarithmicAxisAdditions = /** @class */ (function () { return positions; }; LogarithmicAxisAdditions.prototype.lin2log = function (num) { - var axis = this.axis; - var lin2log = axis.options.linearToLogConverter; - if (typeof lin2log === 'function') { - return lin2log.apply(axis, arguments); - } return Math.pow(10, num); }; LogarithmicAxisAdditions.prototype.log2lin = function (num) { @@ -134,54 +129,32 @@ var LogarithmicAxis = /** @class */ (function () { * @private */ LogarithmicAxis.compose = function (AxisClass) { - var axisProto = AxisClass.prototype; - /** - * @deprecated - * @private - * @function Highcharts.Axis#lin2log - * - * @param {number} num - * - * @return {number} - */ - axisProto.lin2log = function (num) { - var axis = this; - var lin2log = axis.options.linearToLogConverter; - if (typeof lin2log === 'function') { - return lin2log.apply(axis, arguments); - } - return Math.pow(10, num); - }; - /** - * @deprecated - * @private - * @function Highcharts.Axis#log2lin - * - * @param {number} num - * - * @return {number} - */ - axisProto.log2lin = function (num) { - return Math.log(num) / Math.LN10; - }; /* eslint-disable no-invalid-this */ addEvent(AxisClass, 'init', function (e) { var axis = this; + var log = axis.logarithmic; var options = e.userOptions; if (options.type === 'logarithmic') { - axis.logarithmic = new LogarithmicAxisAdditions(axis); + if (!log) { + axis.logarithmic = new LogarithmicAxisAdditions(axis); + } } - else if (axis.logarithmic) { - axis.logarithmic.destroy(); + else if (log) { + log.destroy(); axis.logarithmic = void 0; } }); addEvent(AxisClass, 'afterInit', function () { var axis = this; + var log = axis.logarithmic; // extend logarithmic axis - if (axis.logarithmic) { - axis.val2lin = axis.log2lin; - axis.lin2val = axis.lin2log; + if (log) { + axis.lin2val = function (num) { + return log.lin2log(num); + }; + axis.val2lin = function (num) { + return log.log2lin(num); + }; } }); }; diff --git a/js/parts/PlotLineOrBand.js b/js/parts/PlotLineOrBand.js index ce79cbf8885..21f6d4bef64 100644 --- a/js/parts/PlotLineOrBand.js +++ b/js/parts/PlotLineOrBand.js @@ -61,15 +61,15 @@ var PlotLineOrBand = /** @class */ (function () { */ PlotLineOrBand.prototype.render = function () { H.fireEvent(this, 'render'); - var plotLine = this, axis = plotLine.axis, horiz = axis.horiz, options = plotLine.options, optionsLabel = options.label, label = plotLine.label, to = options.to, from = options.from, value = options.value, isBand = defined(from) && defined(to), isLine = defined(value), svgElem = plotLine.svgElem, isNew = !svgElem, path = [], color = options.color, zIndex = pick(options.zIndex, 0), events = options.events, attribs = { + var plotLine = this, axis = plotLine.axis, horiz = axis.horiz, log = axis.logarithmic, options = plotLine.options, optionsLabel = options.label, label = plotLine.label, to = options.to, from = options.from, value = options.value, isBand = defined(from) && defined(to), isLine = defined(value), svgElem = plotLine.svgElem, isNew = !svgElem, path = [], color = options.color, zIndex = pick(options.zIndex, 0), events = options.events, attribs = { 'class': 'highcharts-plot-' + (isBand ? 'band ' : 'line ') + (options.className || '') }, groupAttribs = {}, renderer = axis.chart.renderer, groupName = isBand ? 'bands' : 'lines', group; // logarithmic conversion - if (axis.logarithmic) { - from = axis.log2lin(from); - to = axis.log2lin(to); - value = axis.log2lin(value); + if (log) { + from = log.log2lin(from); + to = log.log2lin(to); + value = log.log2lin(value); } // Set the presentational attributes if (!axis.chart.styledMode) { diff --git a/js/parts/StockChart.js b/js/parts/StockChart.js index be0119988db..3f420ca0d5c 100644 --- a/js/parts/StockChart.js +++ b/js/parts/StockChart.js @@ -423,7 +423,7 @@ addEvent(Axis, 'afterDrawCrosshair', function (event) { !this.cross) { return; } - var chart = this.chart, options = this.options.crosshair.label, // the label's options + var chart = this.chart, log = this.logarithmic, options = this.options.crosshair.label, // the label's options horiz = this.horiz, // axis orientation opposite = this.opposite, // axis position left = this.left, // left position @@ -432,9 +432,9 @@ addEvent(Axis, 'afterDrawCrosshair', function (event) { posx, posy, crossBox, formatOption = options.format, formatFormat = '', limit, align, tickInside = this.options.tickPosition === 'inside', snap = this.crosshair.snap !== false, value, offset = 0, // Use last available event (#5287) e = event.e || (this.cross && this.cross.e), point = event.point, min = this.min, max = this.max; - if (this.logarithmic) { - min = this.lin2log(min); - max = this.lin2log(max); + if (log) { + min = log.lin2log(min); + max = log.lin2log(max); } align = (horiz ? 'center' : opposite ? (this.labelAlign === 'right' ? 'right' : 'left') : diff --git a/js/parts/Tick.js b/js/parts/Tick.js index bd49e0edd6e..0e0ab475771 100644 --- a/js/parts/Tick.js +++ b/js/parts/Tick.js @@ -103,7 +103,7 @@ var Tick = /** @class */ (function () { * @return {void} */ Tick.prototype.addLabel = function () { - var tick = this, axis = tick.axis, options = axis.options, chart = axis.chart, categories = axis.categories, names = axis.names, pos = tick.pos, labelOptions = pick(tick.options && tick.options.labels, options.labels), str, tickPositions = axis.tickPositions, isFirst = pos === tickPositions[0], isLast = pos === tickPositions[tickPositions.length - 1], value = this.parameters.category || (categories ? + var tick = this, axis = tick.axis, options = axis.options, chart = axis.chart, categories = axis.categories, log = axis.logarithmic, names = axis.names, pos = tick.pos, labelOptions = pick(tick.options && tick.options.labels, options.labels), str, tickPositions = axis.tickPositions, isFirst = pos === tickPositions[0], isLast = pos === tickPositions[tickPositions.length - 1], value = this.parameters.category || (categories ? pick(categories[pos], names[pos], pos) : pos), label = tick.label, animateLabels = (!labelOptions.step || labelOptions.step === 1) && axis.tickInterval === 1, tickPositionInfo = tickPositions.info, dateTimeLabelFormat, dateTimeLabelFormats, i, list; @@ -138,7 +138,7 @@ var Tick = /** @class */ (function () { isLast: isLast, dateTimeLabelFormat: dateTimeLabelFormat, tickPositionInfo: tickPositionInfo, - value: axis.logarithmic ? correctFloat(axis.lin2log(value)) : value, + value: log ? correctFloat(log.lin2log(value)) : value, pos: pos }; str = axis.labelFormatter.call(tick.formatCtx, this.formatCtx); diff --git a/ts/parts-map/ColorAxis.ts b/ts/parts-map/ColorAxis.ts index c671a718302..efe82d5c0b8 100644 --- a/ts/parts-map/ColorAxis.ts +++ b/ts/parts-map/ColorAxis.ts @@ -893,7 +893,7 @@ extend(ColorAxis.prototype, { value: number ): number { if (this.logarithmic) { - value = this.log2lin(value); + value = this.logarithmic.log2lin(value); } return 1 - ( ((this.max as any) - value) / diff --git a/ts/parts/Axis.ts b/ts/parts/Axis.ts index 0f5ac262842..a8a2f2ac9bb 100644 --- a/ts/parts/Axis.ts +++ b/ts/parts/Axis.ts @@ -4838,6 +4838,7 @@ class Axis implements AxisComposition { options = axis.options, min = axis.min, max = axis.max, + log = axis.logarithmic, zoomOffset, spaceAvailable: boolean, closestDataRange: (number|undefined), @@ -4853,7 +4854,7 @@ class Axis implements AxisComposition { if ( axis.isXAxis && typeof axis.minRange === 'undefined' && - !axis.logarithmic + !log ) { if (defined(options.min) || defined(options.max)) { @@ -4901,7 +4902,7 @@ class Axis implements AxisComposition { // If space is available, stay within the data range if (spaceAvailable) { minArgs[2] = axis.logarithmic ? - axis.log2lin(axis.dataMin as any) : + axis.logarithmic.log2lin(axis.dataMin as any) : axis.dataMin; } min = arrayMax(minArgs); @@ -4912,8 +4913,8 @@ class Axis implements AxisComposition { ]; // If space is availabe, stay within the data range if (spaceAvailable) { - maxArgs[2] = axis.logarithmic ? - axis.log2lin(axis.dataMax as any) : + maxArgs[2] = log ? + log.log2lin(axis.dataMax as any) : axis.dataMax; } @@ -5224,6 +5225,7 @@ class Axis implements AxisComposition { public setTickInterval(secondPass?: boolean): void { var axis: Highcharts.Axis = this as any, chart = axis.chart, + log = axis.logarithmic, options = axis.options, isDatetimeAxis = axis.isDatetimeAxis, isXAxis = axis.isXAxis, @@ -5289,7 +5291,7 @@ class Axis implements AxisComposition { } - if (axis.logarithmic) { + if (log) { if ( axis.positiveValuesOnly && !secondPass && @@ -5303,8 +5305,8 @@ class Axis implements AxisComposition { // 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(axis.log2lin(axis.min as any), 16); - axis.max = correctFloat(axis.log2lin(axis.max as any), 16); + axis.min = correctFloat(log.log2lin(axis.min as any), 16); + axis.max = correctFloat(log.log2lin(axis.max as any), 16); } // handle zoomed range @@ -6190,14 +6192,15 @@ class Axis implements AxisComposition { * An object containing extremes information. */ public getExtremes(): Highcharts.ExtremesObject { - var axis: Highcharts.Axis = this as any; + const axis: Highcharts.Axis = this as any; + const log = axis.logarithmic; return { - min: axis.logarithmic ? - correctFloat(axis.lin2log(axis.min as any)) : + min: log ? + correctFloat(log.lin2log(axis.min as any)) : axis.min as any, - max: axis.logarithmic ? - correctFloat(axis.lin2log(axis.max as any)) : + max: log ? + correctFloat(log.lin2log(axis.max as any)) : axis.max as any, dataMin: axis.dataMin as any, dataMax: axis.dataMax as any, @@ -6221,8 +6224,9 @@ class Axis implements AxisComposition { */ public getThreshold(threshold: number): (number|undefined) { var axis: Highcharts.Axis = this as any, - realMin = axis.logarithmic ? axis.lin2log(axis.min as any) : axis.min as any, - realMax = axis.logarithmic ? axis.lin2log(axis.max as any) : axis.max as any; + log = axis.logarithmic, + realMin = log ? log.lin2log(axis.min as any) : axis.min as any, + realMax = log ? log.lin2log(axis.max as any) : axis.max as any; if (threshold === null || threshold === -Infinity) { threshold = realMin; @@ -7194,6 +7198,7 @@ class Axis implements AxisComposition { public render(): void { var axis: Highcharts.Axis = this as any, chart = axis.chart, + log = axis.logarithmic, renderer = chart.renderer, options = axis.options, isLinked = axis.isLinked, @@ -7281,8 +7286,8 @@ class Axis implements AxisComposition { } from = pos + tickmarkOffset; // #949 alternateBands[pos].options = { - from: axis.logarithmic ? axis.lin2log(from) : from, - to: axis.logarithmic ? axis.lin2log(to) : to, + from: log ? log.lin2log(from) : from, + to: log ? log.lin2log(to) : to, color: alternateGridColor }; alternateBands[pos].render(); diff --git a/ts/parts/LogarithmicAxis.ts b/ts/parts/LogarithmicAxis.ts index 5ece3cdbda7..8e7c4c04ab3 100644 --- a/ts/parts/LogarithmicAxis.ts +++ b/ts/parts/LogarithmicAxis.ts @@ -19,21 +19,6 @@ const { pick } = U; -/** - * Internal types - * @private - */ -declare global { - namespace Highcharts { - interface Axis { - /** @deprecated */ - lin2log(num: number): number; - /** @deprecated */ - log2lin(num: number): number; - } - } -} - /* eslint-disable valid-jsdoc */ /** @@ -127,7 +112,7 @@ class LogarithmicAxisAdditions { for (i = roundedMin; i < max + 1 && !break2; i++) { len = intermediate.length; for (j = 0; j < len && !break2; j++) { - pos = axis.log2lin(axis.lin2log(i) * intermediate[j]); + pos = log.log2lin(log.lin2log(i) * intermediate[j]); // #1670, lastPos is #3113 if ( pos > min && @@ -148,8 +133,8 @@ class LogarithmicAxisAdditions { // we might as well handle the tick positions like a linear axis. For // example 1.01, 1.02, 1.03, 1.04. } else { - var realMin = axis.lin2log(min), - realMax = axis.lin2log(max), + var realMin = log.lin2log(min), + realMax = log.lin2log(max), tickIntervalOption = minor ? axis.getMinorTickInterval() : options.tickInterval, @@ -179,7 +164,7 @@ class LogarithmicAxisAdditions { interval, realMin, realMax - ).map(axis.log2lin); + ).map(log.log2lin); if (!minor) { log.minorAutoInterval = interval / 5; @@ -194,13 +179,6 @@ class LogarithmicAxisAdditions { } public lin2log(num: number): number { - const axis = this.axis; - const lin2log = axis.options.linearToLogConverter; - - if (typeof lin2log === 'function') { - return lin2log.apply(axis, arguments); - } - return Math.pow(10, num); } @@ -219,61 +197,34 @@ class LogarithmicAxis { */ public static compose(AxisClass: typeof Axis): void { - const axisProto = AxisClass.prototype as LogarithmicAxis; - - /** - * @deprecated - * @private - * @function Highcharts.Axis#lin2log - * - * @param {number} num - * - * @return {number} - */ - axisProto.lin2log = function (this: Highcharts.Axis, num: number): number { - const axis = this; - const lin2log = axis.options.linearToLogConverter; - - if (typeof lin2log === 'function') { - return lin2log.apply(axis, arguments); - } - - return Math.pow(10, num); - }; - - /** - * @deprecated - * @private - * @function Highcharts.Axis#log2lin - * - * @param {number} num - * - * @return {number} - */ - axisProto.log2lin = function (this: Highcharts.Axis, num: number): number { - return Math.log(num) / Math.LN10; - }; - /* eslint-disable no-invalid-this */ addEvent(AxisClass, 'init', function (e: { userOptions: Axis['options'] }): void { const axis = this; + const log = axis.logarithmic; const options = e.userOptions; if (options.type === 'logarithmic') { - axis.logarithmic = new LogarithmicAxisAdditions(axis as LogarithmicAxis); - } else if (axis.logarithmic) { - axis.logarithmic.destroy(); + if (!log) { + axis.logarithmic = new LogarithmicAxisAdditions(axis as LogarithmicAxis); + } + } else if (log) { + log.destroy(); axis.logarithmic = void 0; } }); addEvent(AxisClass, 'afterInit', function (): void { const axis = this as LogarithmicAxis; + const log = axis.logarithmic; // extend logarithmic axis - if (axis.logarithmic) { - axis.val2lin = axis.log2lin; - axis.lin2val = axis.lin2log; + if (log) { + axis.lin2val = function (num: number): number { + return log.lin2log(num); + }; + axis.val2lin = function (num: number): number { + return log.log2lin(num); + }; } }); } @@ -281,10 +232,6 @@ class LogarithmicAxis { interface LogarithmicAxis extends Axis { logarithmic: LogarithmicAxisAdditions; - /** @deprecated */ - lin2log(num: number): number; - /** @deprecated */ - log2lin(num: number): number; } LogarithmicAxis.compose(Axis); // @todo move to factory functions diff --git a/ts/parts/PlotLineOrBand.ts b/ts/parts/PlotLineOrBand.ts index 8b0082b5087..eda890f3786 100644 --- a/ts/parts/PlotLineOrBand.ts +++ b/ts/parts/PlotLineOrBand.ts @@ -214,6 +214,7 @@ class PlotLineOrBand { var plotLine = this, axis = plotLine.axis, horiz = axis.horiz, + log = axis.logarithmic, options = plotLine.options as ( Highcharts.AxisPlotBandsOptions|Highcharts.AxisPlotLinesOptions ), @@ -240,10 +241,10 @@ class PlotLineOrBand { group; // logarithmic conversion - if (axis.logarithmic) { - from = axis.log2lin(from); - to = axis.log2lin(to); - value = axis.log2lin(value); + if (log) { + from = log.log2lin(from); + to = log.log2lin(to); + value = log.log2lin(value); } // Set the presentational attributes diff --git a/ts/parts/StockChart.ts b/ts/parts/StockChart.ts index b0d5d6802db..b5df244a525 100644 --- a/ts/parts/StockChart.ts +++ b/ts/parts/StockChart.ts @@ -647,6 +647,7 @@ addEvent(Axis, 'afterDrawCrosshair', function ( } var chart = this.chart, + log = this.logarithmic, options = (this.options.crosshair as any).label, // the label's options horiz = this.horiz, // axis orientation opposite = this.opposite, // axis position @@ -670,9 +671,9 @@ addEvent(Axis, 'afterDrawCrosshair', function ( min = this.min, max = this.max; - if (this.logarithmic) { - min = this.lin2log(min as any); - max = this.lin2log(max as any); + if (log) { + min = log.lin2log(min as any); + max = log.lin2log(max as any); } align = (horiz ? 'center' : opposite ? diff --git a/ts/parts/Tick.ts b/ts/parts/Tick.ts index 3c828ec5bc3..47c1bb1046a 100644 --- a/ts/parts/Tick.ts +++ b/ts/parts/Tick.ts @@ -288,6 +288,7 @@ class Tick { options = axis.options, chart = axis.chart, categories = axis.categories, + log = axis.logarithmic, names = axis.names, pos = tick.pos, labelOptions = pick( @@ -351,7 +352,7 @@ class Tick { isLast: isLast, dateTimeLabelFormat: dateTimeLabelFormat as any, tickPositionInfo: tickPositionInfo, - value: axis.logarithmic ? correctFloat(axis.lin2log(value)) : value, + value: log ? correctFloat(log.lin2log(value)) : value, pos: pos }; str = (axis.labelFormatter as any).call(tick.formatCtx, this.formatCtx); From ec14f521d7d066a6203383762611fcebab284536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torstein=20H=C3=B8nsi?= Date: Fri, 27 Mar 2020 10:47:04 +0100 Subject: [PATCH 09/10] Log axis: Added backwards compat hack --- js/parts/LogarithmicAxis.js | 19 ++++++++++++++++++ ts/parts/LogarithmicAxis.ts | 39 +++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/js/parts/LogarithmicAxis.js b/js/parts/LogarithmicAxis.js index 58f764e95a7..2e911456348 100644 --- a/js/parts/LogarithmicAxis.js +++ b/js/parts/LogarithmicAxis.js @@ -130,6 +130,13 @@ var LogarithmicAxis = /** @class */ (function () { */ LogarithmicAxis.compose = function (AxisClass) { /* eslint-disable no-invalid-this */ + // HC <= 8 backwards compatibility, allow wrapping + // Axis.prototype.lin2log and log2lin + // @todo Remove this in next major + var axisProto = AxisClass.prototype; + var logAxisProto = LogarithmicAxisAdditions.prototype; + axisProto.log2lin = logAxisProto.log2lin; + axisProto.lin2log = logAxisProto.lin2log; addEvent(AxisClass, 'init', function (e) { var axis = this; var log = axis.logarithmic; @@ -143,6 +150,18 @@ var LogarithmicAxis = /** @class */ (function () { log.destroy(); axis.logarithmic = void 0; } + // HC <= 8 backwards compatibility, allow wrapping + // Axis.prototype.lin2log and log2lin + // @todo Remove this in next major + var logarithmic = axis.logarithmic; + if (logarithmic) { + if (axis.log2lin !== logarithmic.log2lin) { + logarithmic.log2lin = axis.log2lin.bind(axis); + } + if (axis.lin2log !== logarithmic.lin2log) { + logarithmic.lin2log = axis.lin2log.bind(axis); + } + } }); addEvent(AxisClass, 'afterInit', function () { var axis = this; diff --git a/ts/parts/LogarithmicAxis.ts b/ts/parts/LogarithmicAxis.ts index 8e7c4c04ab3..145c3aafa90 100644 --- a/ts/parts/LogarithmicAxis.ts +++ b/ts/parts/LogarithmicAxis.ts @@ -19,6 +19,24 @@ const { pick } = U; +// HC <= 8 backwards compatibility, allow wrapping Axis.prototype.lin2log and +// log2lin +// @todo Remove this in next major +/** + * Internal, deprecated types + * @private + */ +declare global { + namespace Highcharts { + interface Axis { + /** @deprecated */ + lin2log(num: number): number; + /** @deprecated */ + log2lin(num: number): number; + } + } +} + /* eslint-disable valid-jsdoc */ /** @@ -199,6 +217,14 @@ class LogarithmicAxis { /* eslint-disable no-invalid-this */ + // HC <= 8 backwards compatibility, allow wrapping + // Axis.prototype.lin2log and log2lin + // @todo Remove this in next major + const axisProto = AxisClass.prototype; + const logAxisProto = LogarithmicAxisAdditions.prototype; + axisProto.log2lin = logAxisProto.log2lin; + axisProto.lin2log = logAxisProto.lin2log; + addEvent(AxisClass, 'init', function (e: { userOptions: Axis['options'] }): void { const axis = this; const log = axis.logarithmic; @@ -212,6 +238,19 @@ class LogarithmicAxis { log.destroy(); axis.logarithmic = void 0; } + + // HC <= 8 backwards compatibility, allow wrapping + // Axis.prototype.lin2log and log2lin + // @todo Remove this in next major + const logarithmic = axis.logarithmic; + if (logarithmic) { + if (axis.log2lin !== logarithmic.log2lin) { + logarithmic.log2lin = axis.log2lin.bind(axis); + } + if (axis.lin2log !== logarithmic.lin2log) { + logarithmic.lin2log = axis.lin2log.bind(axis); + } + } }); addEvent(AxisClass, 'afterInit', function (): void { From 6c39dee0d6d96dbeb997bd92f70a3196e87a1fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torstein=20H=C3=B8nsi?= Date: Fri, 27 Mar 2020 11:43:34 +0100 Subject: [PATCH 10/10] Log axis, new snippet for converter functions --- .../demo.js | 56 +++++++------- .../yaxis/type-log-negative-legacy/demo.css | 5 ++ .../type-log-negative-legacy/demo.details | 6 ++ .../yaxis/type-log-negative-legacy/demo.html | 2 + .../yaxis/type-log-negative-legacy/demo.js | 73 +++++++++++++++++++ .../yaxis/type-log-negative/demo.js | 54 +++++++------- ts/parts/Axis.ts | 2 - 7 files changed, 141 insertions(+), 57 deletions(-) create mode 100644 samples/highcharts/yaxis/type-log-negative-legacy/demo.css create mode 100644 samples/highcharts/yaxis/type-log-negative-legacy/demo.details create mode 100644 samples/highcharts/yaxis/type-log-negative-legacy/demo.html create mode 100644 samples/highcharts/yaxis/type-log-negative-legacy/demo.js diff --git a/samples/highcharts/coloraxis/logarithmic-with-emulate-negative-values/demo.js b/samples/highcharts/coloraxis/logarithmic-with-emulate-negative-values/demo.js index b004c7369ae..6ea95136d6d 100644 --- a/samples/highcharts/coloraxis/logarithmic-with-emulate-negative-values/demo.js +++ b/samples/highcharts/coloraxis/logarithmic-with-emulate-negative-values/demo.js @@ -4,38 +4,38 @@ * logarithmic axis never reaches or crosses zero. */ (function (H) { - // Pass error messages - H.addEvent(H.ColorAxis, 'init', function (e) { - this.allowNegativeLog = e.userOptions.allowNegativeLog; - }); + H.addEvent(H.Axis, 'afterInit', function () { + const logarithmic = this.logarithmic; - // Override conversions - H.wrap(H.ColorAxis.prototype, 'log2lin', function (proceed, num) { - if (!this.allowNegativeLog) { - return proceed.call(this, num); - } + if (logarithmic && this.options.allowNegativeLog) { - var isNegative = num < 0, - adjustedNum = Math.abs(num), - result; - if (adjustedNum < 10) { - adjustedNum += (10 - adjustedNum) / 10; - } - result = Math.log(adjustedNum) / Math.LN10; - return isNegative ? -result : result; - }); - H.wrap(H.ColorAxis.prototype, 'lin2log', function (proceed, num) { - if (!this.allowNegativeLog) { - return proceed.call(this, num); - } + // Avoid errors on negative numbers on a log axis + this.positiveValuesOnly = false; + + // Override the converter functions + logarithmic.log2lin = num => { + const isNegative = num < 0; + + let adjustedNum = Math.abs(num); + + if (adjustedNum < 10) { + adjustedNum += (10 - adjustedNum) / 10; + } + + const result = Math.log(adjustedNum) / Math.LN10; + return isNegative ? -result : result; + }; + + logarithmic.lin2log = num => { + const isNegative = num < 0; - var isNegative = num < 0, - absNum = Math.abs(num), - result = Math.pow(10, absNum); - if (result < 10) { - result = (10 * (result - 1)) / (10 - 1); + let result = Math.pow(10, Math.abs(num)); + if (result < 10) { + result = (10 * (result - 1)) / (10 - 1); + } + return isNegative ? -result : result; + }; } - return isNegative ? -result : result; }); }(Highcharts)); diff --git a/samples/highcharts/yaxis/type-log-negative-legacy/demo.css b/samples/highcharts/yaxis/type-log-negative-legacy/demo.css new file mode 100644 index 00000000000..8fd024e55f4 --- /dev/null +++ b/samples/highcharts/yaxis/type-log-negative-legacy/demo.css @@ -0,0 +1,5 @@ +#container { + min-width: 320px; + max-width: 800px; + margin: 0 auto; +} \ No newline at end of file diff --git a/samples/highcharts/yaxis/type-log-negative-legacy/demo.details b/samples/highcharts/yaxis/type-log-negative-legacy/demo.details new file mode 100644 index 00000000000..7b061cbfd99 --- /dev/null +++ b/samples/highcharts/yaxis/type-log-negative-legacy/demo.details @@ -0,0 +1,6 @@ +--- + name: Highcharts Demo + authors: + - Torstein Hønsi + js_wrap: b +... \ No newline at end of file diff --git a/samples/highcharts/yaxis/type-log-negative-legacy/demo.html b/samples/highcharts/yaxis/type-log-negative-legacy/demo.html new file mode 100644 index 00000000000..ee09ee8297d --- /dev/null +++ b/samples/highcharts/yaxis/type-log-negative-legacy/demo.html @@ -0,0 +1,2 @@ + +
\ No newline at end of file diff --git a/samples/highcharts/yaxis/type-log-negative-legacy/demo.js b/samples/highcharts/yaxis/type-log-negative-legacy/demo.js new file mode 100644 index 00000000000..2675a0328e3 --- /dev/null +++ b/samples/highcharts/yaxis/type-log-negative-legacy/demo.js @@ -0,0 +1,73 @@ +/** + * Custom Axis extension to allow emulation of negative values on a logarithmic + * Y axis. Note that the scale is not mathematically correct, as a true + * logarithmic axis never reaches or crosses zero. + */ +(function (H) { + H.addEvent(H.Axis, 'init', function (e) { + this.allowNegativeLog = e.userOptions.allowNegativeLog; + }); + + // Override conversions + H.wrap(H.Axis.prototype, 'log2lin', function (proceed, num) { + + if (!this.allowNegativeLog) { + return proceed.call(this, num); + } + + var isNegative = num < 0, + adjustedNum = Math.abs(num), + result; + if (adjustedNum < 10) { + adjustedNum += (10 - adjustedNum) / 10; + } + result = Math.log(adjustedNum) / Math.LN10; + return isNegative ? -result : result; + }); + H.wrap(H.Axis.prototype, 'lin2log', function (proceed, num) { + if (!this.allowNegativeLog) { + return proceed.call(this, num); + } + + var isNegative = num < 0, + absNum = Math.abs(num), + result = Math.pow(10, absNum); + if (result < 10) { + result = (10 * (result - 1)) / (10 - 1); + } + return isNegative ? -result : result; + }); +}(Highcharts)); + + +Highcharts.chart('container', { + + title: { + text: 'Logarithmic axis with custom conversion allows negative values' + }, + + subtitle: { + text: 'Note: This sample exists for legacy testing purposes and will be removed after version 8', + style: { + color: 'red', + fontSize: 30 + }, + floating: true, + y: 150 + }, + + xAxis: { + categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + }, + + yAxis: { + type: 'logarithmic', + allowNegativeLog: true + }, + + series: [{ + data: [-1000, -100, -10, -1, -0.1, 0, 0.1, 1, 10, 100, 1000] + }] + +}); \ No newline at end of file diff --git a/samples/highcharts/yaxis/type-log-negative/demo.js b/samples/highcharts/yaxis/type-log-negative/demo.js index 62ec555c894..5c0487c0841 100644 --- a/samples/highcharts/yaxis/type-log-negative/demo.js +++ b/samples/highcharts/yaxis/type-log-negative/demo.js @@ -4,38 +4,38 @@ * logarithmic axis never reaches or crosses zero. */ (function (H) { - H.addEvent(H.Axis, 'init', function (e) { - this.allowNegativeLog = e.userOptions.allowNegativeLog; - }); + H.addEvent(H.Axis, 'afterInit', function () { + const logarithmic = this.logarithmic; - // Override conversions - H.wrap(H.Axis.prototype, 'log2lin', function (proceed, num) { + if (logarithmic && this.options.allowNegativeLog) { - if (!this.allowNegativeLog) { - return proceed.call(this, num); - } + // Avoid errors on negative numbers on a log axis + this.positiveValuesOnly = false; - var isNegative = num < 0, - adjustedNum = Math.abs(num), - result; - if (adjustedNum < 10) { - adjustedNum += (10 - adjustedNum) / 10; - } - result = Math.log(adjustedNum) / Math.LN10; - return isNegative ? -result : result; - }); - H.wrap(H.Axis.prototype, 'lin2log', function (proceed, num) { - if (!this.allowNegativeLog) { - return proceed.call(this, num); - } + // Override the converter functions + logarithmic.log2lin = num => { + const isNegative = num < 0; + + let adjustedNum = Math.abs(num); + + if (adjustedNum < 10) { + adjustedNum += (10 - adjustedNum) / 10; + } + + const result = Math.log(adjustedNum) / Math.LN10; + return isNegative ? -result : result; + }; + + logarithmic.lin2log = num => { + const isNegative = num < 0; - var isNegative = num < 0, - absNum = Math.abs(num), - result = Math.pow(10, absNum); - if (result < 10) { - result = (10 * (result - 1)) / (10 - 1); + let result = Math.pow(10, Math.abs(num)); + if (result < 10) { + result = (10 * (result - 1)) / (10 - 1); + } + return isNegative ? -result : result; + }; } - return isNegative ? -result : result; }); }(Highcharts)); diff --git a/ts/parts/Axis.ts b/ts/parts/Axis.ts index a8a2f2ac9bb..323edd49a07 100644 --- a/ts/parts/Axis.ts +++ b/ts/parts/Axis.ts @@ -225,8 +225,6 @@ declare global { isX?: boolean; labels?: XAxisLabelsOptions; left?: (number|string); - /** @deprecated */ - linearToLogConverter?: (num: number) => number; lineColor?: (ColorString|GradientColorObject|PatternObject); lineWidth?: number; linkedTo?: number;