Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/component/axis/CartesianAxisView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import ExtensionAPI from '../../core/ExtensionAPI';
import CartesianAxisModel from '../../coord/cartesian/AxisModel';
import GridModel from '../../coord/cartesian/GridModel';
import { Payload } from '../../util/types';
import { isIntervalOrLogScale } from '../../scale/helper';

const axisBuilderAttrs = [
'axisLine', 'axisTickLabel', 'axisName'
Expand Down Expand Up @@ -69,8 +70,7 @@ class CartesianAxisView extends AxisView {
handleAutoShown(elementType) {
const cartesians = gridModel.coordinateSystem.getCartesians();
for (let i = 0; i < cartesians.length; i++) {
const otherAxisType = cartesians[i].getOtherAxis(axisModel.axis).type;
if (otherAxisType === 'value' || otherAxisType === 'log') {
if (isIntervalOrLogScale(cartesians[i].getOtherAxis(axisModel.axis).scale)) {
// Still show axis tick or axisLine if other axis is value / log
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/component/timeline/SliderTimelineView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ class SliderTimelineView extends TimelineView {

const dataExtent = data.getDataExtent('value');
scale.setExtent(dataExtent[0], dataExtent[1]);
scale.niceTicks();
scale.calcNiceTicks();

const axis = new TimelineAxis('value', scale, layoutInfo.axisExtent as [number, number], axisType);
axis.model = timelineModel;
Expand Down
10 changes: 9 additions & 1 deletion src/coord/axisCommonTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export interface AxisBaseOptionCommon extends ComponentOption,

}

interface NumericAxisBaseOptionCommon extends AxisBaseOptionCommon {
export interface NumericAxisBaseOptionCommon extends AxisBaseOptionCommon {
/*
* The gap at both ends of the axis.
* [GAP, GAP], where
Expand All @@ -105,6 +105,14 @@ interface NumericAxisBaseOptionCommon extends AxisBaseOptionCommon {
* Specify max interval when auto calculate tick interval.
*/
maxInterval?: number;

/**
* If align ticks to the first axis that is not use alignTicks
* If all axes has alignTicks: true. The first one will be applied.
*
* Will be ignored if interval is set.
*/
alignTicks?: boolean
}

export interface CategoryAxisBaseOption extends AxisBaseOptionCommon {
Expand Down
17 changes: 10 additions & 7 deletions src/coord/axisHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,10 @@ function adjustScaleForOverflow(
// Precondition of calling this method:
// The scale extent has been initailized using series data extent via
// `scale.setExtent` or `scale.unionExtentFromData`;
export function niceScaleExtent(scale: Scale, inModel: AxisBaseModel) {
export function niceScaleExtent(
scale: Scale,
inModel: AxisBaseModel
) {
const model = inModel as AxisBaseModel<LogAxisBaseOption>;
const extentInfo = getScaleExtent(scale, model);
const extent = extentInfo.extent;
Expand All @@ -160,23 +163,23 @@ export function niceScaleExtent(scale: Scale, inModel: AxisBaseModel) {
}

const scaleType = scale.type;
const interval = model.get('interval');
const isIntervalOrTime = scaleType === 'interval' || scaleType === 'time';

scale.setExtent(extent[0], extent[1]);
scale.niceExtent({
scale.calcNiceExtent({
splitNumber: splitNumber,
fixMin: extentInfo.fixMin,
fixMax: extentInfo.fixMax,
minInterval: (scaleType === 'interval' || scaleType === 'time')
? model.get('minInterval') : null,
maxInterval: (scaleType === 'interval' || scaleType === 'time')
? model.get('maxInterval') : null
minInterval: isIntervalOrTime ? model.get('minInterval') : null,
maxInterval: isIntervalOrTime ? model.get('maxInterval') : null
});

// If some one specified the min, max. And the default calculated interval
// is not good enough. He can specify the interval. It is often appeared
// in angle axis with angle 0 - 360. Interval calculated in interval scale is hard
// to be 60.
// FIXME
const interval = model.get('interval');
if (interval != null) {
(scale as IntervalScale).setInterval && (scale as IntervalScale).setInterval(interval);
}
Expand Down
82 changes: 60 additions & 22 deletions src/coord/cartesian/Grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* TODO Default cartesian
*/

import {isObject, each, indexOf, retrieve3} from 'zrender/src/core/util';
import {isObject, each, indexOf, retrieve3, map, keys} from 'zrender/src/core/util';
import {getLayoutRect, LayoutRect} from '../../util/layout';
import {
createScaleByModel,
Expand All @@ -47,14 +47,20 @@ import { ScaleDataValue } from '../../util/types';
import SeriesData from '../../data/SeriesData';
import OrdinalScale from '../../scale/Ordinal';
import { isCartesian2DSeries, findAxisModels } from './cartesianAxisHelper';
import { CategoryAxisBaseOption } from '../axisCommonTypes';
import { CategoryAxisBaseOption, NumericAxisBaseOptionCommon } from '../axisCommonTypes';
import { AxisBaseModel } from '../AxisBaseModel';
import { alignScaleTicks, isIntervalOrLogScale } from '../../scale/helper';
import IntervalScale from '../../scale/Interval';
import LogScale from '../../scale/Log';


type Cartesian2DDimensionName = 'x' | 'y';

type FinderAxisIndex = {xAxisIndex?: number, yAxisIndex?: number};
type AxesMap = {x: Axis2D[], y: Axis2D[]};
type AxesMap = {
x: Axis2D[],
y: Axis2D[]
};

class Grid implements CoordinateSystemMaster {

Expand Down Expand Up @@ -92,12 +98,55 @@ class Grid implements CoordinateSystemMaster {

this._updateScale(ecModel, this.model);

each(axesMap.x, function (xAxis) {
niceScaleExtent(xAxis.scale, xAxis.model);
});
each(axesMap.y, function (yAxis) {
niceScaleExtent(yAxis.scale, yAxis.model);
});
function updateAxisTicks(axes: Record<number, Axis2D>) {
let alignTo: Axis2D;
// Axis is added in order of axisIndex.
const axesIndices = keys(axes);
const len = axesIndices.length;
if (!len) {
return;
}
const axisNeedsAlign: Axis2D[] = [];
// Process once and calculate the ticks for those don't use alignTicks.
for (let i = len - 1; i >= 0; i--) {
const idx = +axesIndices[i]; // Convert to number.
const axis = axes[idx];
const model = axis.model as AxisBaseModel<NumericAxisBaseOptionCommon>;
const scale = axis.scale;
if (// Only value and log axis without interval support alignTicks.
isIntervalOrLogScale(scale)
&& model.get('alignTicks')
&& model.get('interval') == null
) {
axisNeedsAlign.push(axis);
}
else {
niceScaleExtent(scale, model);
if (isIntervalOrLogScale(scale)) { // Can only align to interval or log axis.
alignTo = axis;
}
}
};
// All axes has set alignTicks. Pick the first one.
// PENDING. Should we find the axis that both set interval, min, max and align to this one?
if (axisNeedsAlign.length) {
if (!alignTo) {
alignTo = axisNeedsAlign.pop();
niceScaleExtent(alignTo.scale, alignTo.model);
}

each(axisNeedsAlign, axis => {
alignScaleTicks(
axis.scale as IntervalScale | LogScale,
axis.model,
alignTo.scale as IntervalScale | LogScale
);
});
}
}

updateAxisTicks(axesMap.x);
updateAxisTicks(axesMap.y);

// Key: axisDim_axisIndex, value: boolean, whether onZero target.
const onZeroRecords = {} as Dictionary<boolean>;
Expand Down Expand Up @@ -177,15 +226,6 @@ class Grid implements CoordinateSystemMaster {
const axesMapOnDim = this._axesMap[dim];
if (axesMapOnDim != null) {
return axesMapOnDim[axisIndex || 0];
// if (axisIndex == null) {
// Find first axis
// for (let name in axesMapOnDim) {
// if (axesMapOnDim.hasOwnProperty(name)) {
// return axesMapOnDim[name];
// }
// }
// }
// return axesMapOnDim[axisIndex];
}
}

Expand Down Expand Up @@ -445,10 +485,8 @@ class Grid implements CoordinateSystemMaster {
const xAxis = cartesian.getAxis('x');
const yAxis = cartesian.getAxis('y');

if (data.type === 'list') {
unionExtent(data, xAxis);
unionExtent(data, yAxis);
}
unionExtent(data, xAxis);
unionExtent(data, yAxis);
}
}, this);

Expand Down
77 changes: 9 additions & 68 deletions src/coord/radar/Radar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,14 @@
import IndicatorAxis from './IndicatorAxis';
import IntervalScale from '../../scale/Interval';
import * as numberUtil from '../../util/number';
import {
getScaleExtent,
niceScaleExtent
} from '../axisHelper';
import { CoordinateSystemMaster, CoordinateSystem } from '../CoordinateSystem';
import RadarModel from './RadarModel';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import { ScaleDataValue } from '../../util/types';
import { ParsedModelFinder } from '../../util/model';
import { parseAxisModelMinMax } from '../scaleRawExtentInfo';
import { map, each } from 'zrender/src/core/util';
import { alignScaleTicks } from '../../scale/helper';


class Radar implements CoordinateSystem, CoordinateSystemMaster {
Expand Down Expand Up @@ -172,71 +168,16 @@ class Radar implements CoordinateSystem, CoordinateSystemMaster {
}, this);

const splitNumber = radarModel.get('splitNumber');

function increaseInterval(interval: number) {
const exp10 = Math.pow(10, Math.floor(Math.log(interval) / Math.LN10));
// Increase interval
let f = interval / exp10;
if (f === 2) {
f = 5;
}
else { // f is 2 or 5
f *= 2;
}
return f * exp10;
}
const dummyScale = new IntervalScale();
dummyScale.setExtent(0, splitNumber);
dummyScale.setInterval(1);
// Force all the axis fixing the maxSplitNumber.
each(indicatorAxes, function (indicatorAxis, idx) {
const rawExtent = getScaleExtent(indicatorAxis.scale, indicatorAxis.model).extent;
niceScaleExtent(indicatorAxis.scale, indicatorAxis.model);

const axisModel = indicatorAxis.model;
const scale = indicatorAxis.scale as IntervalScale;
const fixedMin = parseAxisModelMinMax(scale, axisModel.get('min', true) as ScaleDataValue);
const fixedMax = parseAxisModelMinMax(scale, axisModel.get('max', true) as ScaleDataValue);
let interval = scale.getInterval();

if (fixedMin != null && fixedMax != null) {
// User set min, max, divide to get new interval
scale.setExtent(+fixedMin, +fixedMax);
scale.setInterval(
(fixedMax - fixedMin) / splitNumber
);
}
else if (fixedMin != null) {
let max;
// User set min, expand extent on the other side
do {
max = fixedMin + interval * splitNumber;
scale.setExtent(+fixedMin, max);
// Interval must been set after extent
// FIXME
scale.setInterval(interval);

interval = increaseInterval(interval);
} while (max < rawExtent[1] && isFinite(max) && isFinite(rawExtent[1]));
}
else if (fixedMax != null) {
let min;
// User set min, expand extent on the other side
do {
min = fixedMax - interval * splitNumber;
scale.setExtent(min, +fixedMax);
scale.setInterval(interval);
interval = increaseInterval(interval);
} while (min > rawExtent[0] && isFinite(min) && isFinite(rawExtent[0]));
}
else {
const nicedSplitNumber = scale.getTicks().length - 1;
if (nicedSplitNumber > splitNumber) {
interval = increaseInterval(interval);
}
// TODO
const max = Math.ceil(rawExtent[1] / interval) * interval;
const min = numberUtil.round(max - interval * splitNumber);
scale.setExtent(min, max);
scale.setInterval(interval);
}
alignScaleTicks(
indicatorAxis.scale as IntervalScale,
indicatorAxis.model,
dummyScale
);
});
}

Expand Down
10 changes: 6 additions & 4 deletions src/scale/Interval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ class IntervalScale<SETTING extends Dictionary<unknown> = Dictionary<unknown>> e
/**
* @param splitNumber By default `5`.
*/
niceTicks(splitNumber?: number, minInterval?: number, maxInterval?: number): void {
calcNiceTicks(splitNumber?: number, minInterval?: number, maxInterval?: number): void {
splitNumber = splitNumber || 5;
const extent = this._extent;
let span = extent[1] - extent[0];
Expand All @@ -238,7 +238,7 @@ class IntervalScale<SETTING extends Dictionary<unknown> = Dictionary<unknown>> e
this._niceExtent = result.niceTickExtent;
}

niceExtent(opt: {
calcNiceExtent(opt: {
splitNumber: number, // By default 5.
fixMin?: boolean,
fixMax?: boolean,
Expand Down Expand Up @@ -275,8 +275,7 @@ class IntervalScale<SETTING extends Dictionary<unknown> = Dictionary<unknown>> e
extent[1] = 1;
}

this.niceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval);

this.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval);
// let extent = this._extent;
const interval = this._interval;

Expand All @@ -288,6 +287,9 @@ class IntervalScale<SETTING extends Dictionary<unknown> = Dictionary<unknown>> e
}
}

setNiceExtent(min: number, max: number) {
this._niceExtent = [min, max];
}
}

Scale.registerClass(IntervalScale);
Expand Down
9 changes: 4 additions & 5 deletions src/scale/Log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class LogScale extends Scale {
/**
* @param Whether expand the ticks to niced extent.
*/
getTicks(expandToNicedExtent: boolean): ScaleTick[] {
getTicks(expandToNicedExtent?: boolean): ScaleTick[] {
const originalScale = this._originalScale;
const extent = this._extent;
const originalExtent = originalScale.getExtent();
Expand Down Expand Up @@ -128,7 +128,7 @@ class LogScale extends Scale {
* Update interval and extent of intervals for nice ticks
* @param approxTickNum default 10 Given approx tick number
*/
niceTicks(approxTickNum: number): void {
calcNiceTicks(approxTickNum: number): void {
approxTickNum = approxTickNum || 10;
const extent = this._extent;
const span = extent[1] - extent[0];
Expand Down Expand Up @@ -158,14 +158,14 @@ class LogScale extends Scale {
this._niceExtent = niceExtent;
}

niceExtent(opt: {
calcNiceExtent(opt: {
splitNumber: number, // By default 5.
fixMin?: boolean,
fixMax?: boolean,
minInterval?: number,
maxInterval?: number
}): void {
intervalScaleProto.niceExtent.call(this, opt);
intervalScaleProto.calcNiceExtent.call(this, opt);

this._fixMin = opt.fixMin;
this._fixMax = opt.fixMax;
Expand Down Expand Up @@ -198,7 +198,6 @@ const proto = LogScale.prototype;
proto.getMinorTicks = intervalScaleProto.getMinorTicks;
proto.getLabel = intervalScaleProto.getLabel;


function fixRoundingError(val: number, originalVal: number): number {
return roundingErrorFix(val, numberUtil.getPrecision(originalVal));
}
Expand Down
Loading