@@ -46,26 +46,35 @@ import CartesianAxisModel from './cartesian/AxisModel';
4646import SeriesData from '../data/SeriesData' ;
4747import { getStackedDimension } from '../data/helper/dataStackHelper' ;
4848import { Dictionary , DimensionName , ScaleTick } from '../util/types' ;
49- import { ensureScaleRawExtentInfo } from './scaleRawExtentInfo' ;
49+ import { ensureScaleRawExtentInfo , ScaleRawExtentResult } from './scaleRawExtentInfo' ;
5050import { parseTimeAxisLabelFormatter } from '../util/time' ;
5151import { getScaleBreakHelper } from '../scale/break' ;
5252import { error } from '../util/log' ;
53+ import { isIntervalScale , isTimeScale } from '../scale/helper' ;
5354
5455
5556type BarWidthAndOffset = ReturnType < typeof makeColumnLayout > ;
5657
5758/**
58- * Get axis scale extent before niced.
59+ * Prepare axis scale extent before niced.
5960 * Item of returned array can only be number (including Infinity and NaN).
6061 *
61- * Caution:
62- * Precondition of calling this method:
63- * The scale extent has been initialized using series data extent via
64- * `scale.setExtent` or `scale.unionExtentFromData`;
62+ * CAVEAT:
63+ * This function has side-effect.
64+ *
65+ * FIXME:
66+ * Refector to decouple `unionExtentFromData` and irregular value handling from `scale`.
67+ * Merge `unionAxisExtentFromData` and `unionExtentFromData`.
68+ * Refector `ensureScaleRawExtentInfo`.
6569 */
66- export function getScaleExtent ( scale : Scale , model : AxisBaseModel ) {
67- const scaleType = scale . type ;
68- const rawExtentResult = ensureScaleRawExtentInfo ( scale , model , scale . getExtent ( ) ) . calculate ( ) ;
70+ export function adoptScaleExtentOptionAndPrepare (
71+ scale : Scale ,
72+ model : AxisBaseModel ,
73+ // Typically: data extent from all series on this axis.
74+ // Can be obtained by `scale.unionExtentFromData(); scale.getExtent()`;
75+ dataExtent : number [ ]
76+ ) : ScaleRawExtentResult {
77+ const rawExtentResult = ensureScaleRawExtentInfo ( scale , model , dataExtent ) . calculate ( ) ;
6978
7079 scale . setBlank ( rawExtentResult . isBlank ) ;
7180
@@ -82,7 +91,7 @@ export function getScaleExtent(scale: Scale, model: AxisBaseModel) {
8291 // (4) Consider other chart types using `barGrid`?
8392 // See #6728, #4862, `test/bar-overflow-time-plot.html`
8493 const ecModel = model . ecModel ;
85- if ( ecModel && ( scaleType === 'time' /* || scaleType === 'interval' */ ) ) {
94+ if ( ecModel && ( isTimeScale ( scale ) /* || scaleType === 'interval' */ ) ) {
8695 const barSeriesModels = prepareLayoutBarSeries ( 'bar' , ecModel ) ;
8796 let isBaseAxisAndHasBarSeries = false ;
8897
@@ -102,13 +111,10 @@ export function getScaleExtent(scale: Scale, model: AxisBaseModel) {
102111 }
103112 }
104113
105- return {
106- extent : [ min , max ] ,
107- // "fix" means "fixed", the value should not be
108- // changed in the subsequent steps.
109- fixMin : rawExtentResult . minFixed ,
110- fixMax : rawExtentResult . maxFixed
111- } ;
114+ rawExtentResult . min = min ;
115+ rawExtentResult . max = max ;
116+
117+ return rawExtentResult ;
112118}
113119
114120function adjustScaleForOverflow (
@@ -151,32 +157,25 @@ function adjustScaleForOverflow(
151157 return { min : min , max : max } ;
152158}
153159
154- // Precondition of calling this method:
155- // The scale extent has been initialized using series data extent via
156- // `scale.setExtent` or `scale.unionExtentFromData`;
157160export function niceScaleExtent (
158161 scale : Scale ,
159- inModel : AxisBaseModel
160- ) {
162+ inModel : AxisBaseModel ,
163+ // Typically: data extent from all series on this axis, which can be obtained by
164+ // `scale.unionExtentFromData(...); scale.getExtent();`.
165+ dataExtent : number [ ] ,
166+ ) : void {
161167 const model = inModel as AxisBaseModel < LogAxisBaseOption > ;
162- const extentInfo = getScaleExtent ( scale , model ) ;
163- const extent = extentInfo . extent ;
164- const splitNumber = model . get ( 'splitNumber' ) ;
165-
166- if ( scale instanceof LogScale ) {
167- scale . base = model . get ( 'logBase' ) ;
168- }
168+ const extentInfo = adoptScaleExtentOptionAndPrepare ( scale , model , dataExtent ) ;
169169
170- const scaleType = scale . type ;
171- const interval = model . get ( 'interval' ) ;
172- const isIntervalOrTime = scaleType === 'interval' || scaleType === 'time' ;
170+ const isInterval = isIntervalScale ( scale ) ;
171+ const isIntervalOrTime = isInterval || isTimeScale ( scale ) ;
173172
174173 scale . setBreaksFromOption ( retrieveAxisBreaksOption ( model ) ) ;
175- scale . setExtent ( extent [ 0 ] , extent [ 1 ] ) ;
174+ scale . setExtent ( extentInfo . min , extentInfo . max ) ;
176175 scale . calcNiceExtent ( {
177- splitNumber : splitNumber ,
178- fixMin : extentInfo . fixMin ,
179- fixMax : extentInfo . fixMax ,
176+ splitNumber : model . get ( ' splitNumber' ) ,
177+ fixMin : extentInfo . minFixed ,
178+ fixMax : extentInfo . maxFixed ,
180179 minInterval : isIntervalOrTime ? model . get ( 'minInterval' ) : null ,
181180 maxInterval : isIntervalOrTime ? model . get ( 'maxInterval' ) : null
182181 } ) ;
@@ -185,36 +184,35 @@ export function niceScaleExtent(
185184 // is not good enough. He can specify the interval. It is often appeared
186185 // in angle axis with angle 0 - 360. Interval calculated in interval scale is hard
187186 // to be 60.
188- // FIXME
189- if ( interval != null ) {
190- ( scale as IntervalScale ) . setInterval && ( scale as IntervalScale ) . setInterval ( interval ) ;
187+ // In `xxxAxis.type: 'log'`, ec option `xxxAxis.interval` requires a logarithm-applied
188+ // value rather than a value in the raw scale.
189+ const interval = model . get ( 'interval' ) ;
190+ if ( interval != null && ( scale as IntervalScale ) . setInterval ) {
191+ ( scale as IntervalScale ) . setInterval ( { interval} ) ;
191192 }
192193}
193194
194- /**
195- * @param axisType Default retrieve from model.type
196- */
197- export function createScaleByModel ( model : AxisBaseModel , axisType ?: string ) : Scale {
198- axisType = axisType || model . get ( 'type' ) ;
199- if ( axisType ) {
200- switch ( axisType ) {
201- // Buildin scale
202- case 'category' :
203- return new OrdinalScale ( {
204- ordinalMeta : model . getOrdinalMeta
205- ? model . getOrdinalMeta ( )
206- : model . getCategories ( ) ,
207- extent : [ Infinity , - Infinity ]
208- } ) ;
209- case 'time' :
210- return new TimeScale ( {
211- locale : model . ecModel . getLocaleModel ( ) ,
212- useUTC : model . ecModel . get ( 'useUTC' ) ,
213- } ) ;
214- default :
215- // case 'value'/'interval', 'log', or others.
216- return new ( Scale . getClass ( axisType ) || IntervalScale ) ( ) ;
217- }
195+ export function createScaleByModel ( model : AxisBaseModel ) : Scale {
196+ const axisType = model . get ( 'type' ) ;
197+ switch ( axisType ) {
198+ case 'category' :
199+ return new OrdinalScale ( {
200+ ordinalMeta : model . getOrdinalMeta
201+ ? model . getOrdinalMeta ( )
202+ : model . getCategories ( ) ,
203+ extent : [ Infinity , - Infinity ]
204+ } ) ;
205+ case 'time' :
206+ return new TimeScale ( {
207+ locale : model . ecModel . getLocaleModel ( ) ,
208+ useUTC : model . ecModel . get ( 'useUTC' ) ,
209+ } ) ;
210+ case 'log' :
211+ // See also #3749
212+ return new LogScale ( ( model as AxisBaseModel < LogAxisBaseOption > ) . get ( 'logBase' ) ) ;
213+ default :
214+ // case 'value'/'interval', or others.
215+ return new ( Scale . getClass ( axisType ) || IntervalScale ) ( ) ;
218216 }
219217}
220218
@@ -303,7 +301,6 @@ export function getAxisRawValue<TIsCategory extends boolean>(axis: Axis, tick: S
303301
304302/**
305303 * @param model axisLabelModel or axisTickModel
306- * @return {number|String } Can be null|'auto'|number|function
307304 */
308305export function getOptionCategoryInterval (
309306 model : Model < AxisBaseOption [ 'axisLabel' ] >
0 commit comments