diff --git a/src/component/marker/checkMarkerInSeries.ts b/src/component/marker/checkMarkerInSeries.ts index 5f87a4c358..12ad5b9476 100644 --- a/src/component/marker/checkMarkerInSeries.ts +++ b/src/component/marker/checkMarkerInSeries.ts @@ -20,7 +20,7 @@ import { isArray } from 'zrender/src/core/util'; import { SeriesOption } from '../../util/types'; -type MarkerTypes = 'markPoint' | 'markLine' | 'markArea'; +export type MarkerTypes = 'markPoint' | 'markLine' | 'markArea'; type SeriesWithMarkerOption = SeriesOption & Partial>; diff --git a/src/coord/cartesian/AxisModel.ts b/src/coord/cartesian/AxisModel.ts index 1b0d35a137..f502d9013e 100644 --- a/src/coord/cartesian/AxisModel.ts +++ b/src/coord/cartesian/AxisModel.ts @@ -37,6 +37,8 @@ export type CartesianAxisOption = AxisBaseOption & { // Offset is for multiple axis on the same position. offset?: number; categorySortInfo?: OrdinalSortInfo; + // Whether to include marker data (markPoint, markLine, markArea) in axis extent calculation + includeMarkerInExtent?: boolean; }; export type XAXisOption = CartesianAxisOption & { diff --git a/src/coord/cartesian/Grid.ts b/src/coord/cartesian/Grid.ts index 97ac081bf0..ba5164ce2e 100644 --- a/src/coord/cartesian/Grid.ts +++ b/src/coord/cartesian/Grid.ts @@ -44,7 +44,7 @@ import GlobalModel from '../../model/Global'; import ExtensionAPI from '../../core/ExtensionAPI'; import { Dictionary } from 'zrender/src/core/types'; import {CoordinateSystemMaster} from '../CoordinateSystem'; -import { NullUndefined, ScaleDataValue } from '../../util/types'; +import { NullUndefined, ScaleDataValue, SeriesOption } from '../../util/types'; import SeriesData from '../../data/SeriesData'; import OrdinalScale from '../../scale/Ordinal'; import { @@ -53,7 +53,7 @@ import { updateCartesianAxisViewCommonPartBuilder, isCartesian2DInjectedAsDataCoordSys } from './cartesianAxisHelper'; -import { CategoryAxisBaseOption, NumericAxisBaseOptionCommon } from '../axisCommonTypes'; +import { CategoryAxisBaseOption, NumericAxisBaseOptionCommon, OptionAxisType } from '../axisCommonTypes'; import { AxisBaseModel } from '../AxisBaseModel'; import { isIntervalOrLogScale } from '../../scale/helper'; import { alignScaleTicks } from '../axisAlignTicks'; @@ -70,6 +70,7 @@ import { error, log } from '../../util/log'; import { AxisTickLabelComputingKind } from '../axisTickLabelBuilder'; import { injectCoordSysByOption } from '../../core/CoordinateSystem'; import { mathMax, parsePositionSizeOption } from '../../util/number'; +import { MarkerTypes } from '../../component/marker/checkMarkerInSeries'; type Cartesian2DDimensionName = 'x' | 'y'; @@ -542,6 +543,16 @@ class Grid implements CoordinateSystemMaster { unionExtent(data, xAxis); unionExtent(data, yAxis); + + // Handle markPoint, markLine, markArea + const markerTypes: MarkerTypes[] = ['markPoint', 'markLine', 'markArea']; + + markerTypes.forEach(markerType => { + const markerOpt = seriesModel.get(markerType as keyof SeriesOption); + if (markerOpt && markerOpt.data) { + unionMarkerExtent(markerOpt.data, xAxis, yAxis); + } + }); } }, this); @@ -550,6 +561,48 @@ class Grid implements CoordinateSystemMaster { axis.scale.unionExtentFromData(data, dim); }); } + + function unionExtentForAxisByValue( + value: any, + axis: Axis2D, + axisType: OptionAxisType, + ): void { + const includeMarkerInExtent = axis.model.get('includeMarkerInExtent') ?? false; + const isValidNumber = typeof value === 'number' && !isNaN(value); + if (includeMarkerInExtent && (isValidNumber || typeof value === 'string') && axisType !== 'category') { + const val = axis.scale.parse(value); + if (!isNaN(val)) { + axis.scale.unionExtentByValue(val); + } + } + } + + function unionMarkerExtent( + markerData: any[], + xAxis: Axis2D, + yAxis: Axis2D, + ): void { + each(markerData, function (item) { + if (!item) { + return; + } + const items = Array.isArray(item) ? item : [item]; + + each(items, function (markerItem) { + if (!markerItem) { + return; + } + + unionExtentForAxisByValue(markerItem.xAxis, xAxis, xAxis.type); + unionExtentForAxisByValue(markerItem.yAxis, yAxis, yAxis.type); + + if (markerItem.coord && Array.isArray(markerItem.coord)) { + unionExtentForAxisByValue(markerItem.coord[0], xAxis, xAxis.type); + unionExtentForAxisByValue(markerItem.coord[1], yAxis, yAxis.type); + } + }); + }); + } } /** diff --git a/src/scale/Log.ts b/src/scale/Log.ts index bdd799056c..18ffd2974c 100644 --- a/src/scale/Log.ts +++ b/src/scale/Log.ts @@ -134,6 +134,12 @@ class LogScale extends IntervalScale { this._innerUnionExtent(loggedOther); } + unionExtentByValue(value: number): void { + this._originalScale.unionExtentByValue(value); + const loggedValue = logTransform(this.base, [value, value], true); + this._innerUnionExtent(loggedValue); + } + /** * Update interval and extent of intervals for nice ticks * @param approxTickNum default 10 Given approx tick number diff --git a/src/scale/Scale.ts b/src/scale/Scale.ts index 1f1fbdecf2..f613b217e6 100644 --- a/src/scale/Scale.ts +++ b/src/scale/Scale.ts @@ -133,6 +133,18 @@ abstract class Scale this._innerUnionExtent(data.getApproximateExtent(dim)); } + /** + * Update extent by value + */ + unionExtentByValue(value: number): void { + const extent = this._extent; + // Considered that number could be NaN and should not write into the extent. + this._innerSetExtent( + value < extent[0] ? value : extent[0], + value > extent[1] ? value : extent[1] + ); + } + /** * Get a new slice of extent. * Extent is always in increase order. diff --git a/test/axis-marker-extent.html b/test/axis-marker-extent.html new file mode 100644 index 0000000000..cc1525d02b --- /dev/null +++ b/test/axis-marker-extent.html @@ -0,0 +1,546 @@ + + + + + + + + + + + +
仅有 markLine(includeMarkerInExtent: false)
+
+
+
+
+ +
仅有 markLine
+
+
+
+
+ +
markLine为负值用例
+
+
+
+
+ +
仅有 markLine(includeMarkerInExtent未设置)
+
+
+
+
+ +
仅有 markPoint
+
+
+
+
+ +
仅有 markArea
+
+
+
+
+ + +
Bar Chart(水平)基于 markLine 用例
+
+
+
+
+ + +
x轴为 time 类型
+
+
+
+
+
y轴为 log 类型
+
+
+
+
+ + + +