From c99223559a4a55174bb0da75c85f13cb11f5430b Mon Sep 17 00:00:00 2001 From: Jakub Januchta Date: Fri, 29 Dec 2023 09:57:21 +0100 Subject: [PATCH] Added #20275, xAxis overscroll possible in pixels or percentage. --- samples/unit-tests/axis/overscroll/demo.js | 48 ++++++++++++++++ ts/Core/Axis/AxisOptions.d.ts | 2 +- ts/Core/Axis/OrdinalAxis.ts | 65 +++++++++++++++++++--- ts/Stock/Navigator/Navigator.ts | 4 +- 4 files changed, 109 insertions(+), 10 deletions(-) diff --git a/samples/unit-tests/axis/overscroll/demo.js b/samples/unit-tests/axis/overscroll/demo.js index 336cca65134..d467d0ba2dd 100644 --- a/samples/unit-tests/axis/overscroll/demo.js +++ b/samples/unit-tests/axis/overscroll/demo.js @@ -192,4 +192,52 @@ ); } ); + + QUnit.test( + 'Ordinal: ' + ordinal + ' - Extremes for overscroll in px', + function (assert) { + const options = getOptions(), + overscrollPixelValue = 300; + + options.rangeSelector.selected = null; + options.xAxis.overscroll = options.navigator.xAxis.overscroll = 0; + + const xAxis = Highcharts.stockChart('container', options).xAxis[0], + xAxisRange = xAxis.max - xAxis.min; + + xAxis.update({ + overscroll: overscrollPixelValue + 'px' + }); + + assert.strictEqual( + xAxis.max - xAxis.min, + xAxisRange + (overscrollPixelValue / xAxis.width) * xAxisRange, + 'Correct range with overscroll set in px ' + ); + } + ); + + QUnit.test( + 'Ordinal: ' + ordinal + ' - Extremes for overscroll in %', + function (assert) { + const options = getOptions(), + overscrollPercentageValue = 50; + + options.rangeSelector.selected = null; + options.xAxis.overscroll = options.navigator.xAxis.overscroll = 0; + + const xAxis = Highcharts.stockChart('container', options).xAxis[0], + xAxisRange = xAxis.max - xAxis.min; + + xAxis.update({ + overscroll: overscrollPercentageValue + '%' + }); + + assert.strictEqual( + xAxis.max - xAxis.min, + xAxisRange + overscrollPercentageValue / 100 * xAxisRange, + 'Correct range with overscroll set in % ' + ); + } + ); }); diff --git a/ts/Core/Axis/AxisOptions.d.ts b/ts/Core/Axis/AxisOptions.d.ts index 626d47f7d57..252b849e098 100644 --- a/ts/Core/Axis/AxisOptions.d.ts +++ b/ts/Core/Axis/AxisOptions.d.ts @@ -166,7 +166,7 @@ export interface AxisOptions { offsets?: [number, number, number, number]; opposite?: boolean; ordinal?: boolean; - overscroll?: number; + overscroll?: number | string; pane?: number; panningEnabled: boolean; range?: number; diff --git a/ts/Core/Axis/OrdinalAxis.ts b/ts/Core/Axis/OrdinalAxis.ts index 01553c4d692..7b5a3fb3910 100644 --- a/ts/Core/Axis/OrdinalAxis.ts +++ b/ts/Core/Axis/OrdinalAxis.ts @@ -163,6 +163,8 @@ namespace OrdinalAxis { onAxisFoundExtremes ); addEvent(AxisClass, 'afterSetScale', onAxisAfterSetScale); + // addEvent(AxisClass as (T&typeof Composition), + // 'afterSetScale', onAxisFoundExtremes); addEvent( AxisClass, 'initialAxisTranslation', @@ -529,11 +531,15 @@ namespace OrdinalAxis { axis.eventArgs && axis.eventArgs.trigger !== 'navigator' ) ) { - (axis.max as any) += (axis.options.overscroll as any); + const overscroll = axis.ordinal.convertOverscroll( + axis.options.overscroll + ); + + (axis.max as any) += overscroll; // Live data and buttons require translation for the min: if (!axis.isInternal && defined(axis.userMin)) { - (axis.min as any) += (axis.options.overscroll as any); + (axis.min as any) += overscroll; } } } @@ -575,7 +581,9 @@ namespace OrdinalAxis { function onChartPan(this: Chart, e: Event): void { const chart = this, xAxis = chart.xAxis[0] as OrdinalAxis.Composition, - overscroll = xAxis.options.overscroll, + overscroll = xAxis.ordinal.convertOverscroll( + xAxis.options.overscroll + ), chartX = (e as any).originalEvent.chartX, panning = chart.options.chart.panning; let runBase = false; @@ -679,8 +687,7 @@ namespace OrdinalAxis { // Apply it if it is within the available data range if ( trimmedRange.min >= Math.min(extremes.dataMin, min) && - trimmedRange.max <= Math.max(dataMax, max) + - (overscroll as any) + trimmedRange.max <= Math.max(dataMax, max) + overscroll ) { xAxis.setExtremes( trimmedRange.min, @@ -1041,7 +1048,9 @@ namespace OrdinalAxis { } else if (len === 1) { // We have just one point, closest distance is unknown. // Assume then it is last point and overscrolled range: - overscrollPointsRange = axis.options.overscroll; + overscrollPointsRange = axis.ordinal.convertOverscroll( + axis.options.overscroll + ); ordinalPositions = [ ordinalPositions[0], ordinalPositions[0] + overscrollPointsRange @@ -1168,7 +1177,9 @@ namespace OrdinalAxis { key = grouping ? grouping.count + (grouping.unitName as any) : 'raw', - overscroll = axis.options.overscroll, + overscroll = axis.ordinal.convertOverscroll( + axis.options.overscroll + ), extremes = axis.getExtremes(); let fakeAxis: Composition, fakeSeries: Series = void 0 as any, @@ -1428,7 +1439,9 @@ namespace OrdinalAxis { public getOverscrollPositions(): Array { const ordinal = this, axis = ordinal.axis, - extraRange = axis.options.overscroll, + extraRange = ordinal.convertOverscroll( + axis.options.overscroll + ), distance = ordinal.overscrollPointsRange, positions = []; @@ -1481,6 +1494,42 @@ namespace OrdinalAxis { return ret; } + /** + * If overscroll is pixel or pecentage value, convert it to axis range. + * + * @private + * @function Highcharts.Axis#convertOverscroll + * @param {number | string} overscroll + * Overscroll value in axis range, pixels or percentage value. + * @return {number} + * Overscroll value in axis range. + */ + public convertOverscroll(overscroll : number | string | undefined) + : number { + const ordinal = this, + axis = ordinal.axis, + overscrollValue = parseInt(overscroll as any, 10); + + if (/%$/.test(overscroll as any)) { + // If overscroll is percentage + return ((axis.max as any) - (axis.min as any)) * + overscrollValue / 100; + } + + if (/px/.test(overscroll as any)) { + // If overscroll is pixels + return ((axis.max as any) - (axis.min as any)) * + overscrollValue / axis.width; + } + + if (isNaN(overscrollValue)) { + // If overscroll is a string but not pixels or percentage, + // return 0 as no overscroll + return 0; + } + + return overscrollValue; + } } } diff --git a/ts/Stock/Navigator/Navigator.ts b/ts/Stock/Navigator/Navigator.ts index 8e5eba7b99b..47efe892796 100644 --- a/ts/Stock/Navigator/Navigator.ts +++ b/ts/Stock/Navigator/Navigator.ts @@ -1852,7 +1852,9 @@ class Navigator { range = baseMax - baseMin, stickToMin = (navigator as any).stickToMin, stickToMax = (navigator as any).stickToMax, - overscroll = pick(baseXAxis.options.overscroll, 0), + overscroll = pick(baseXAxis.ordinal?.convertOverscroll( + baseXAxis.options.overscroll + ), 0), navigatorSeries = (navigator as any).series && (navigator as any).series[0], hasSetExtremes = !!baseXAxis.setExtremes,