前端初始化

This commit is contained in:
“hsc”
2026-08-21 15:36:24 +08:00
commit e4d8ecde13
14411 changed files with 2275932 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import Axis from '../Axis.js';
var Axis2D = /** @class */function (_super) {
__extends(Axis2D, _super);
function Axis2D(dim, scale, coordExtent, axisType, position) {
var _this = _super.call(this, dim, scale, coordExtent) || this;
/**
* Index of axis, can be used as key
* Injected outside.
*/
_this.index = 0;
_this.type = axisType || 'value';
_this.position = position || 'bottom';
return _this;
}
Axis2D.prototype.isHorizontal = function () {
var position = this.position;
return position === 'top' || position === 'bottom';
};
/**
* Each item cooresponds to this.getExtent(), which
* means globalExtent[0] may greater than globalExtent[1],
* unless `asc` is input.
*
* @param {boolean} [asc]
* @return {Array.<number>}
*/
Axis2D.prototype.getGlobalExtent = function (asc) {
var ret = this.getExtent();
ret[0] = this.toGlobalCoord(ret[0]);
ret[1] = this.toGlobalCoord(ret[1]);
asc && ret[0] > ret[1] && ret.reverse();
return ret;
};
Axis2D.prototype.pointToData = function (point, clamp) {
return this.coordToData(this.toLocalCoord(point[this.dim === 'x' ? 0 : 1]), clamp);
};
/**
* Set ordinalSortInfo
* @param info new OrdinalSortInfo
*/
Axis2D.prototype.setCategorySortInfo = function (info) {
if (this.type !== 'category') {
return false;
}
this.model.option.categorySortInfo = info;
this.scale.setSortInfo(info);
};
return Axis2D;
}(Axis);
export default Axis2D;
+62
View File
@@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import ComponentModel from '../../model/Component.js';
import { AxisModelCommonMixin } from '../axisModelCommonMixin.js';
import { SINGLE_REFERRING } from '../../util/model.js';
var CartesianAxisModel = /** @class */function (_super) {
__extends(CartesianAxisModel, _super);
function CartesianAxisModel() {
return _super !== null && _super.apply(this, arguments) || this;
}
CartesianAxisModel.prototype.getCoordSysModel = function () {
return this.getReferringComponents('grid', SINGLE_REFERRING).models[0];
};
CartesianAxisModel.type = 'cartesian2dAxis';
return CartesianAxisModel;
}(ComponentModel);
export { CartesianAxisModel };
zrUtil.mixin(CartesianAxisModel, AxisModelCommonMixin);
export default CartesianAxisModel;
+74
View File
@@ -0,0 +1,74 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
var Cartesian = /** @class */function () {
function Cartesian(name) {
this.type = 'cartesian';
this._dimList = [];
this._axes = {};
this.name = name || '';
}
Cartesian.prototype.getAxis = function (dim) {
return this._axes[dim];
};
Cartesian.prototype.getAxes = function () {
return zrUtil.map(this._dimList, function (dim) {
return this._axes[dim];
}, this);
};
Cartesian.prototype.getAxesByScale = function (scaleType) {
scaleType = scaleType.toLowerCase();
return zrUtil.filter(this.getAxes(), function (axis) {
return axis.scale.type === scaleType;
});
};
Cartesian.prototype.addAxis = function (axis) {
var dim = axis.dim;
this._axes[dim] = axis;
this._dimList.push(dim);
};
return Cartesian;
}();
;
export default Cartesian;
+182
View File
@@ -0,0 +1,182 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import BoundingRect from 'zrender/lib/core/BoundingRect.js';
import Cartesian from './Cartesian.js';
import { COORD_SYS_TYPE_CARTESIAN_2D } from './GridModel.js';
import { invert } from 'zrender/lib/core/matrix.js';
import { applyTransform } from 'zrender/lib/core/vector.js';
import { getScaleExtentForMappingUnsafe } from '../../scale/scaleMapper.js';
import { hasBreaks } from '../../scale/break.js';
export var cartesian2DDimensions = ['x', 'y'];
function canCalculateAffineTransform(scale) {
// Only supported on linear space.
return (scale.type === 'interval' || scale.type === 'time') && !hasBreaks(scale);
}
var Cartesian2D = /** @class */function (_super) {
__extends(Cartesian2D, _super);
function Cartesian2D() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = COORD_SYS_TYPE_CARTESIAN_2D;
_this.dimensions = cartesian2DDimensions;
return _this;
}
/**
* Calculate an affine transform matrix if two axes are time or value.
* It's mainly for accelartion on the large time series data.
*/
Cartesian2D.prototype.calcAffineTransform = function () {
this._transform = this._invTransform = null;
var xAxisScale = this.getAxis('x').scale;
var yAxisScale = this.getAxis('y').scale;
if (!canCalculateAffineTransform(xAxisScale) || !canCalculateAffineTransform(yAxisScale)) {
return;
}
var xScaleExtent = getScaleExtentForMappingUnsafe(xAxisScale, null);
var yScaleExtent = getScaleExtentForMappingUnsafe(yAxisScale, null);
var start = this.dataToPoint([xScaleExtent[0], yScaleExtent[0]]);
var end = this.dataToPoint([xScaleExtent[1], yScaleExtent[1]]);
var xScaleSpan = xScaleExtent[1] - xScaleExtent[0];
var yScaleSpan = yScaleExtent[1] - yScaleExtent[0];
if (!xScaleSpan || !yScaleSpan) {
return;
}
// Accelerate data to point calculation on the special large time series data.
var scaleX = (end[0] - start[0]) / xScaleSpan;
var scaleY = (end[1] - start[1]) / yScaleSpan;
var translateX = start[0] - xScaleExtent[0] * scaleX;
var translateY = start[1] - yScaleExtent[0] * scaleY;
var m = this._transform = [scaleX, 0, 0, scaleY, translateX, translateY];
this._invTransform = invert([], m);
};
/**
* Base axis will be used on stacking and series such as 'bar', 'pictorialBar', etc.
*/
Cartesian2D.prototype.getBaseAxis = function () {
// FIXME:
// (1) We should allow series (e.g., bar) to specify a base axis when
// both axes are type "value", rather than force to xAxis or angleAxis.
// NOTE: At present BoxplotSeries has its own overide `getBaseAxis`.
// `CoordinateSystem['getBaseAxis']` probably should not exist, since it
// may introduce inconsistency with `Series['getBaseAxis']`.
// (2) "base axis" info is required in "createSeriesData" stage for "stack",
// (see `dataStackHelper.ts` for details). Currently it is hard coded there.
return this.getAxesByScale('ordinal')[0] || this.getAxesByScale('time')[0] || this.getAxis('x');
};
Cartesian2D.prototype.containPoint = function (point) {
var axisX = this.getAxis('x');
var axisY = this.getAxis('y');
return axisX.contain(axisX.toLocalCoord(point[0])) && axisY.contain(axisY.toLocalCoord(point[1]));
};
Cartesian2D.prototype.containData = function (data) {
return this.getAxis('x').containData(data[0]) && this.getAxis('y').containData(data[1]);
};
Cartesian2D.prototype.containZone = function (data1, data2) {
var zoneDiag1 = this.dataToPoint(data1);
var zoneDiag2 = this.dataToPoint(data2);
var area = this.getArea();
var zone = new BoundingRect(zoneDiag1[0], zoneDiag1[1], zoneDiag2[0] - zoneDiag1[0], zoneDiag2[1] - zoneDiag1[1]);
return area.intersect(zone);
};
Cartesian2D.prototype.dataToPoint = function (data, clamp, out) {
out = out || [];
var xVal = data[0];
var yVal = data[1];
// [CAVEAT]: Do not add time consuming operation within and before fast path.
// Fast path.
if (this._transform
// It's supported that if data is like `[Inifity, 123]`, where only Y pixel calculated.
&& xVal != null && isFinite(xVal) && yVal != null && isFinite(yVal)) {
return applyTransform(out, data, this._transform);
}
var xAxis = this.getAxis('x');
var yAxis = this.getAxis('y');
out[0] = xAxis.toGlobalCoord(xAxis.dataToCoord(xVal, clamp));
out[1] = yAxis.toGlobalCoord(yAxis.dataToCoord(yVal, clamp));
return out;
};
Cartesian2D.prototype.clampData = function (data, out) {
var xScale = this.getAxis('x').scale;
var yScale = this.getAxis('y').scale;
var xAxisExtent = xScale.getExtent();
var yAxisExtent = yScale.getExtent();
var x = xScale.parse(data[0]);
var y = yScale.parse(data[1]);
out = out || [];
out[0] = Math.min(Math.max(Math.min(xAxisExtent[0], xAxisExtent[1]), x), Math.max(xAxisExtent[0], xAxisExtent[1]));
out[1] = Math.min(Math.max(Math.min(yAxisExtent[0], yAxisExtent[1]), y), Math.max(yAxisExtent[0], yAxisExtent[1]));
return out;
};
Cartesian2D.prototype.pointToData = function (point, clamp, out) {
out = out || [];
if (this._invTransform) {
return applyTransform(out, point, this._invTransform);
}
var xAxis = this.getAxis('x');
var yAxis = this.getAxis('y');
out[0] = xAxis.coordToData(xAxis.toLocalCoord(point[0]), clamp);
out[1] = yAxis.coordToData(yAxis.toLocalCoord(point[1]), clamp);
return out;
};
Cartesian2D.prototype.getOtherAxis = function (axis) {
return this.getAxis(axis.dim === 'x' ? 'y' : 'x');
};
/**
* Get rect area of cartesian.
* Area will have a contain function to determine if a point is in the coordinate system.
*/
Cartesian2D.prototype.getArea = function (tolerance) {
tolerance = tolerance || 0;
var xExtent = this.getAxis('x').getGlobalExtent();
var yExtent = this.getAxis('y').getGlobalExtent();
var x = Math.min(xExtent[0], xExtent[1]) - tolerance;
var y = Math.min(yExtent[0], yExtent[1]) - tolerance;
var width = Math.max(xExtent[0], xExtent[1]) - x + tolerance;
var height = Math.max(yExtent[0], yExtent[1]) - y + tolerance;
return new BoundingRect(x, y, width, height);
};
return Cartesian2D;
}(Cartesian);
;
export default Cartesian2D;
+801
View File
@@ -0,0 +1,801 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Grid is a region which contains at most 4 cartesian systems
*
* TODO Default cartesian
*/
import { isObject, each, indexOf, retrieve3, keys, assert, eqNaN, find, retrieve2, hasOwn } from 'zrender/lib/core/util.js';
import { createBoxLayoutReference, getLayoutRect } from '../../util/layout.js';
import { createScaleByModel, getScaleValuePositionKind, isNameLocationCenter, shouldAxisShow, retrieveAxisBreaksOption, determineAxisType, isOnAxisZeroDiscouraged, SCALE_VALUE_POSITION_KIND_OUTSIDE, getTickValueOutermost, isAxisOnBand } from '../../coord/axisHelper.js';
import Cartesian2D, { cartesian2DDimensions } from './Cartesian2D.js';
import Axis2D from './Axis2D.js';
import { SINGLE_REFERRING } from '../../util/model.js';
// Depends on GridModel, AxisModel, which performs preprocess.
import { COORD_SYS_TYPE_CARTESIAN_2D, OUTER_BOUNDS_CLAMP_DEFAULT, OUTER_BOUNDS_DEFAULT } from './GridModel.js';
import { findAxisModels, createCartesianAxisViewCommonPartBuilder, updateCartesianAxisViewCommonPartBuilder } from './cartesianAxisHelper.js';
import { isIntervalOrLogScale, isOrdinalScale } from '../../scale/helper.js';
import { scaleCalcAlign } from '../axisAlignTicks.js';
import { expandOrShrinkRect, WH, XY } from '../../util/graphic.js';
import { AxisBuilderSharedContext, resolveAxisNameOverlapDefault, moveIfOverlapByLinearLabels, getLabelInner } from '../../component/axis/AxisBuilder.js';
import { error, log } from '../../util/log.js';
import { AxisTickLabelComputingKind } from '../axisTickLabelBuilder.js';
import { injectCoordSysByOption } from '../../core/CoordinateSystem.js';
import { mathMax, parsePositionSizeOption } from '../../util/number.js';
import { scaleCalcNice } from '../axisNiceTicks.js';
import { createDimNameMap } from '../../data/helper/SeriesDataSchema.js';
import { AXIS_EXTENT_INFO_BUILD_FROM_COORD_SYS_UPDATE, scaleRawExtentInfoEnableBoxCoordSysUsage, scaleRawExtentInfoCreate } from '../scaleRawExtentInfo.js';
import { hasBreaks } from '../../scale/break.js';
import { associateSeriesWithAxis } from '../axisStatistics.js';
// margin is [top, right, bottom, left]
var XY_TO_MARGIN_IDX = [[3, 1], [0, 2] // xyIdx 1 => 'y'
];
var Grid = /** @class */function () {
function Grid(gridModel, ecModel, api) {
// FIXME:TS where used (different from registered type 'cartesian2d')?
this.type = 'grid';
this._coordsMap = {};
this._coordsList = [];
this._axesMap = {};
this._axesList = [];
this.axisPointerEnabled = true;
this.dimensions = cartesian2DDimensions;
this._initCartesian(gridModel, ecModel, api);
this.model = gridModel;
}
Grid.prototype.getRect = function () {
return this._rect;
};
Grid.prototype.update = function (ecModel, api) {
var axesMap = this._axesMap;
each(this._axesList, function (axis) {
scaleRawExtentInfoCreate(axis, AXIS_EXTENT_INFO_BUILD_FROM_COORD_SYS_UPDATE);
var scale = axis.scale;
if (isOrdinalScale(scale)) {
scale.setSortInfo(axis.model.get('categorySortInfo'));
}
});
function updateAxisTicks(axes) {
// Axis is added in order of axisIndex.
var axesIndices = keys(axes);
var axisNeedsAlign = [];
for (var i = axesIndices.length - 1; i >= 0; i--) {
// Reverse order
var axis = axes[+axesIndices[i]];
if (axis.__alignTo) {
axisNeedsAlign.push(axis);
} else {
scaleCalcNice(axis);
}
}
;
each(axisNeedsAlign, function (axis) {
if (incapableOfAlignNeedFallback(axis, axis.__alignTo)) {
scaleCalcNice(axis);
} else {
scaleCalcAlign(axis, axis.__alignTo.scale);
}
});
}
updateAxisTicks(axesMap.x);
updateAxisTicks(axesMap.y);
// Key: axisDim_axisIndex, value: boolean, whether onZero target.
var onZeroRecords = {};
each(axesMap.x, function (xAxis) {
fixAxisOnZero(axesMap, 'y', xAxis, onZeroRecords);
});
each(axesMap.y, function (yAxis) {
fixAxisOnZero(axesMap, 'x', yAxis, onZeroRecords);
});
// Resize again if containLabel is enabled
// FIXME It may cause getting wrong grid size in data processing stage
this.resize(this.model, api);
};
/**
* Resize the grid.
*
* [NOTE]
* If both "grid.containLabel/grid.contain" and pixel-required-data-processing (such as, "dataSampling")
* exist, circular dependency occurs in logic.
* The final compromised sequence is:
* 1. Calculate "axis.extent" (pixel extent) and AffineTransform based on only "grid layout options".
* Not accurate if "grid.containLabel/grid.contain" is required, but it is a compromise to avoid
* circular dependency.
* 2. Perform "series data processing" (where "dataSampling" requires "axis.extent").
* 3. Calculate "scale.extent" (data extent) based on "processed series data".
* 4. Modify "axis.extent" for "grid.containLabel/grid.contain":
* 4.1. Calculate "axis labels" based on "scale.extent".
* 4.2. Modify "axis.extent" by the bounding rects of "axis labels and names".
*/
Grid.prototype.resize = function (gridModel, api, beforeDataProcessing) {
var layoutRef = createBoxLayoutReference(gridModel, api);
var gridRect = this._rect = getLayoutRect(gridModel.getBoxLayoutParams(), layoutRef.refContainer);
// PENDING: whether to support that if the input `coord` is out of the base coord sys,
// do not render anything. At present, the behavior is undefined.
var axesMap = this._axesMap;
var coordsList = this._coordsList;
var optionContainLabel = gridModel.get('containLabel'); // No `.get(, true)` for backward compat.
// NOTE: The axis pixel extent is also required by some estimation, e.g., in coord sys update stage,
// bars on 'time'/'value' axis need it to calculate the supplementary scale extent to avoid edge bars
// overflowing the axis (see `barGrid.ts`). Therefore, axis pixel extent need to be set early, even
// may not be accurate.
updateAllAxisExtentTransByGridRect(axesMap, gridRect);
if (!beforeDataProcessing) {
var axisBuilderSharedCtx = createAxisBiulders(gridRect, coordsList, axesMap, optionContainLabel, api);
var noPxChange = void 0;
if (optionContainLabel) {
if (legacyLayOutGridByContainLabel) {
// console.time('legacyLayOutGridByContainLabel');
legacyLayOutGridByContainLabel(this._axesList, gridRect);
updateAllAxisExtentTransByGridRect(axesMap, gridRect);
// console.timeEnd('legacyLayOutGridByContainLabel');
} else {
if (process.env.NODE_ENV !== 'production') {
log('Specified `grid.containLabel` but no `use(LegacyGridContainLabel)`;' + 'use `grid.outerBounds` instead.', true);
}
noPxChange = layOutGridByOuterBounds(gridRect.clone(), 'axisLabel', null, gridRect, axesMap, axisBuilderSharedCtx, layoutRef);
}
} else {
var _a = prepareOuterBounds(gridModel, gridRect, layoutRef),
outerBoundsRect = _a.outerBoundsRect,
parsedOuterBoundsContain = _a.parsedOuterBoundsContain,
outerBoundsClamp = _a.outerBoundsClamp;
if (outerBoundsRect) {
// console.time('layOutGridByOuterBounds');
noPxChange = layOutGridByOuterBounds(outerBoundsRect, parsedOuterBoundsContain, outerBoundsClamp, gridRect, axesMap, axisBuilderSharedCtx, layoutRef);
// console.timeEnd('layOutGridByOuterBounds');
}
}
// console.time('buildAxesView_determine');
createOrUpdateAxesView(gridRect, axesMap, AxisTickLabelComputingKind.determine, null, noPxChange, layoutRef);
// console.timeEnd('buildAxesView_determine');
each(this._coordsList, function (coord) {
// Calculate affine matrix to accelerate the data to point transform.
// If all the axes scales are time or value.
coord.calcAffineTransform();
});
} // End of beforeDataProcessing
};
Grid.prototype.getAxis = function (dim, axisIndex) {
var axesMapOnDim = this._axesMap[dim];
if (axesMapOnDim != null) {
return axesMapOnDim[axisIndex || 0];
}
};
Grid.prototype.getAxes = function () {
return this._axesList.slice();
};
Grid.prototype.getCartesian = function (xAxisIndex, yAxisIndex) {
if (xAxisIndex != null && yAxisIndex != null) {
var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
return this._coordsMap[key];
}
if (isObject(xAxisIndex)) {
yAxisIndex = xAxisIndex.yAxisIndex;
xAxisIndex = xAxisIndex.xAxisIndex;
}
for (var i = 0, coordList = this._coordsList; i < coordList.length; i++) {
if (coordList[i].getAxis('x').index === xAxisIndex || coordList[i].getAxis('y').index === yAxisIndex) {
return coordList[i];
}
}
};
Grid.prototype.getCartesians = function () {
return this._coordsList.slice();
};
/**
* @implements
*/
Grid.prototype.convertToPixel = function (ecModel, finder, value) {
var target = this._findConvertTarget(finder);
return target.cartesian ? target.cartesian.dataToPoint(value) : target.axis ? target.axis.toGlobalCoord(target.axis.dataToCoord(value)) : null;
};
/**
* @implements
*/
Grid.prototype.convertFromPixel = function (ecModel, finder, value) {
var target = this._findConvertTarget(finder);
return target.cartesian ? target.cartesian.pointToData(value) : target.axis ? target.axis.coordToData(target.axis.toLocalCoord(value)) : null;
};
Grid.prototype._findConvertTarget = function (finder) {
var seriesModel = finder.seriesModel;
var xAxisModel = finder.xAxisModel || seriesModel && seriesModel.getReferringComponents('xAxis', SINGLE_REFERRING).models[0];
var yAxisModel = finder.yAxisModel || seriesModel && seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[0];
var gridModel = finder.gridModel;
var coordsList = this._coordsList;
var cartesian;
var axis;
if (seriesModel) {
cartesian = seriesModel.coordinateSystem;
indexOf(coordsList, cartesian) < 0 && (cartesian = null);
} else if (xAxisModel && yAxisModel) {
cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
} else if (xAxisModel) {
axis = this.getAxis('x', xAxisModel.componentIndex);
} else if (yAxisModel) {
axis = this.getAxis('y', yAxisModel.componentIndex);
}
// Lowest priority.
else if (gridModel) {
var grid = gridModel.coordinateSystem;
if (grid === this) {
cartesian = this._coordsList[0];
}
}
return {
cartesian: cartesian,
axis: axis
};
};
/**
* @implements
*/
Grid.prototype.containPoint = function (point) {
var coord = this._coordsList[0];
if (coord) {
return coord.containPoint(point);
}
};
/**
* Initialize cartesian coordinate systems
*/
Grid.prototype._initCartesian = function (gridModel, ecModel, api) {
var _this = this;
var grid = this;
var axisPositionUsed = {
left: false,
right: false,
top: false,
bottom: false
};
var axesMap = {
x: {},
y: {}
};
var axesCount = {
x: 0,
y: 0
};
// Create axis
ecModel.eachComponent('xAxis', createAxisCreator('x'), this);
ecModel.eachComponent('yAxis', createAxisCreator('y'), this);
if (!axesCount.x || !axesCount.y) {
// Roll back when there no either x or y axis
this._axesMap = {};
this._axesList = [];
return;
}
this._axesMap = axesMap;
// Create cartesian2d
each(axesMap.x, function (xAxis, xAxisIndex) {
each(axesMap.y, function (yAxis, yAxisIndex) {
var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
var cartesian = new Cartesian2D(key);
cartesian.master = _this;
cartesian.model = gridModel;
_this._coordsMap[key] = cartesian;
_this._coordsList.push(cartesian);
cartesian.addAxis(xAxis);
cartesian.addAxis(yAxis);
});
});
prepareAlignToInCoordSysCreate(axesMap.x);
prepareAlignToInCoordSysCreate(axesMap.y);
function createAxisCreator(dimName) {
return function (axisModel, idx) {
if (!isAxisUsedInTheGrid(axisModel, gridModel)) {
return;
}
var axisPosition = axisModel.get('position');
if (dimName === 'x') {
// Fix position
if (axisPosition !== 'top' && axisPosition !== 'bottom') {
// Default bottom of X
axisPosition = axisPositionUsed.bottom ? 'top' : 'bottom';
}
} else {
// Fix position
if (axisPosition !== 'left' && axisPosition !== 'right') {
// Default left of Y
axisPosition = axisPositionUsed.left ? 'right' : 'left';
}
}
axisPositionUsed[axisPosition] = true;
var axisType = determineAxisType(axisModel);
var axis = new Axis2D(dimName, createScaleByModel(axisModel, axisType, true), [0, 0], axisType, axisPosition);
axis.onBand = isAxisOnBand(axis.scale, axisModel);
axis.inverse = axisModel.get('inverse');
// Inject axis into axisModel
axisModel.axis = axis;
// Inject axisModel into axis
axis.model = axisModel;
// Inject grid info axis
axis.grid = grid;
// Index of axis, can be used as key
axis.index = idx;
grid._axesList.push(axis);
axesMap[dimName][idx] = axis;
axesCount[dimName]++;
};
}
};
/**
* @param dim 'x' or 'y' or 'auto' or null/undefined
*/
Grid.prototype.getTooltipAxes = function (dim) {
var baseAxes = [];
var otherAxes = [];
each(this.getCartesians(), function (cartesian) {
var baseAxis = dim != null && dim !== 'auto' ? cartesian.getAxis(dim) : cartesian.getBaseAxis();
var otherAxis = cartesian.getOtherAxis(baseAxis);
indexOf(baseAxes, baseAxis) < 0 && baseAxes.push(baseAxis);
indexOf(otherAxes, otherAxis) < 0 && otherAxes.push(otherAxis);
});
return {
baseAxes: baseAxes,
otherAxes: otherAxes
};
};
Grid.create = function (ecModel, api) {
var grids = [];
ecModel.eachComponent('grid', function (gridModel, idx) {
var grid = new Grid(gridModel, ecModel, api);
grid.name = 'grid_' + idx;
// dataSampling requires axis extent, so resize
// should be performed in create stage.
grid.resize(gridModel, api, true);
gridModel.coordinateSystem = grid;
grids.push(grid);
each(grid._axesList, function (axis) {
scaleRawExtentInfoEnableBoxCoordSysUsage(axis, Grid.dimIdxMap);
});
});
// Inject the coordinateSystems into seriesModel
ecModel.eachSeries(function (seriesModel) {
var xAxis;
var yAxis;
injectCoordSysByOption({
targetModel: seriesModel,
coordSysType: COORD_SYS_TYPE_CARTESIAN_2D,
coordSysProvider: coordSysProvider
});
function coordSysProvider() {
var axesModelMap = findAxisModels(seriesModel);
var xAxisModel = axesModelMap.xAxisModel;
var yAxisModel = axesModelMap.yAxisModel;
xAxis = xAxisModel.axis;
yAxis = yAxisModel.axis;
var gridModel = xAxisModel.getCoordSysModel();
if (process.env.NODE_ENV !== 'production') {
if (!gridModel) {
throw new Error('Grid "' + retrieve3(xAxisModel.get('gridIndex'), xAxisModel.get('gridId'), 0) + '" not found');
}
if (xAxisModel.getCoordSysModel() !== yAxisModel.getCoordSysModel()) {
throw new Error('xAxis and yAxis must use the same grid');
}
}
var grid = gridModel.coordinateSystem;
return grid.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
}
if (xAxis && yAxis) {
associateSeriesWithAxis(xAxis, seriesModel, COORD_SYS_TYPE_CARTESIAN_2D);
associateSeriesWithAxis(yAxis, seriesModel, COORD_SYS_TYPE_CARTESIAN_2D);
}
}, this);
return grids;
};
// For deciding which dimensions to use when creating list data
Grid.dimensions = cartesian2DDimensions;
Grid.dimIdxMap = createDimNameMap(cartesian2DDimensions);
return Grid;
}();
/**
* Check if the axis is used in the specified grid.
*/
function isAxisUsedInTheGrid(axisModel, gridModel) {
return axisModel.getCoordSysModel() === gridModel;
}
function fixAxisOnZero(axesMap, otherAxisDim, axis,
// Key: see `getOnZeroRecordKey`
onZeroRecords) {
axis.getAxesOnZeroOf = function () {
// TODO: onZero of multiple axes.
return otherAxisOnZeroOf ? [otherAxisOnZeroOf] : [];
};
// onZero can not be enabled in these two situations:
// 1. When any other axis is a category axis.
// 2. When no axis is cross 0 point.
var otherAxes = axesMap[otherAxisDim];
var otherAxisOnZeroOf;
var axisModel = axis.model;
var onZero = axisModel.get(['axisLine', 'onZero']);
var onZeroAxisIndex = axisModel.get(['axisLine', 'onZeroAxisIndex']);
// For historical reason, ec option `axisLine.onZero: undefined` leads to "not on zero"
// while leaving `axisLine.onZero` unspecified causes "on zero". This inconsistency goes
// against common sense, but is preserved for backward compatibility.
if (!onZero) {
return;
}
// If target axis is specified.
if (onZeroAxisIndex != null) {
if (canOnZeroToAxis(onZero, otherAxes[onZeroAxisIndex])) {
otherAxisOnZeroOf = otherAxes[onZeroAxisIndex];
}
} else {
// Find the first available other axis.
for (var idx in otherAxes) {
if (hasOwn(otherAxes, idx) && canOnZeroToAxis(onZero, otherAxes[idx])
// Consider that two Y axes on one value axis,
// if both onZero, the two Y axes overlap.
&& !onZeroRecords[getOnZeroRecordKey(otherAxes[idx])]) {
otherAxisOnZeroOf = otherAxes[idx];
break;
}
}
}
if (otherAxisOnZeroOf) {
onZeroRecords[getOnZeroRecordKey(otherAxisOnZeroOf)] = true;
}
function getOnZeroRecordKey(axis) {
return axis.dim + '_' + axis.index;
}
}
/**
* CAVEAT: Must not be called before `CoordinateSystem#update` due to `__dontOnMyZero`.
*/
function canOnZeroToAxis(onZeroOption, axis) {
if (!axis) {
return false;
}
var scale = axis.scale;
var kindEffective = getScaleValuePositionKind(scale, 0, false);
var can = axis
// PENDING: Historical behavior: `onZero` on 'category' and 'time' axis are always disabled
// even if ec option gives `onZero: true`.
&& axis.type !== 'category' && axis.type !== 'time'
// NOTE: Although the portion out of "effective" portion may also cross zero
// (see `SCALE_EXTENT_KIND_MAPPING`), that is commonly meaningless, so we use
// `SCALE_EXTENT_KIND_EFFECTIVE`
&& kindEffective !== SCALE_VALUE_POSITION_KIND_OUTSIDE;
if (can && onZeroOption === 'auto'
// Historically, "value" axis and "log" axis has been using `onZero: true` as the default.
// It suitable for mathematic cases, even when dataZoom exists (e.g., `clip.html`), or cases
// need to distinguish positive and negative data. However, it probably causes odd effect if
// a "value axis" is laid on zero of a "base axis" in bar/candlestick, where the axis line
// would likely cross shapes when `SCALE_EXTENT_KIND_MAPPING` is applied.
// Therefore, we preserve backward compatibility of the default `onZero: true`, but exclude
// cases that `containShape` is applied.
&& isOnAxisZeroDiscouraged(axis)
// || (
// // Avoid axis line cross series shape (typically, bar series on "value"/"time" axis) unexpectedly.
// kindEffective === SCALE_VALUE_POSITION_KIND_EDGE
// && getScaleValuePositionKind(scale, 0, true) === SCALE_VALUE_POSITION_KIND_INSIDE
// )
) {
can = false;
}
// falsy value of `onZeroOption` has been handled in the previous logic.
return can;
}
/**
* [CAVEAT] This method is called before data processing stage.
* Do not rely on any info that is determined afterward.
*/
function prepareAlignToInCoordSysCreate(axes) {
// Axis is added in order of axisIndex.
var axesIndices = keys(axes);
var alignTo;
var axisNeedsAlign = [];
for (var i = axesIndices.length - 1; i >= 0; i--) {
// Reverse order
var axis = axes[+axesIndices[i]];
if (isIntervalOrLogScale(axis.scale)
// NOTE: `scale.hasBreaks()` is not available at this moment. Check it later.
&& retrieveAxisBreaksOption(axis.model, axis.type, true) == null
// NOTE: `scale.getTicks()` is not available at this moment. Check it later.
) {
// Request `alignTicks`.
if (axis.model.get('alignTicks') && axis.model.get('interval') == null) {
axisNeedsAlign.push(axis);
} else {
// `alignTo` the last one that does not request `alignTicks`
// (This rule is retained for backward compat).
alignTo = axis;
}
}
}
;
// If all axes has set alignTicks, pick the first one as alignTo.
// PENDING. Should we find the axis that both set interval, min, max and align to this one?
// PENDING. Should we allow specifying alignTo via ec option?
if (!alignTo) {
alignTo = axisNeedsAlign.pop();
}
if (alignTo) {
each(axisNeedsAlign, function (axis) {
axis.__alignTo = alignTo;
});
}
}
/**
* This is just a defence code. They are unlikely to be actually `true`,
* since these cases have been addressed in `prepareAlignToInCoordSysCreate`.
*
* Can not be called BEFORE "nice" performed.
*/
function incapableOfAlignNeedFallback(targetAxis, alignTo) {
return hasBreaks(targetAxis.scale) || hasBreaks(alignTo.scale)
// Normally ticks length are more than 2 even when axis is blank.
// But still guard for corner cases and possible changes.
|| alignTo.scale.getTicks().length < 2;
}
function updateAxisTransform(axis, coordBase) {
var axisExtent = axis.getExtent();
var axisExtentSum = axisExtent[0] + axisExtent[1];
// Fast transform
axis.toGlobalCoord = axis.dim === 'x' ? function (coord) {
return coord + coordBase;
} : function (coord) {
return axisExtentSum - coord + coordBase;
};
axis.toLocalCoord = axis.dim === 'x' ? function (coord) {
return coord - coordBase;
} : function (coord) {
return axisExtentSum - coord + coordBase;
};
}
function updateAllAxisExtentTransByGridRect(axesMap, gridRect) {
each(axesMap.x, function (axis) {
return updateAxisExtentTransByGridRect(axis, gridRect.x, gridRect.width);
});
each(axesMap.y, function (axis) {
return updateAxisExtentTransByGridRect(axis, gridRect.y, gridRect.height);
});
}
function updateAxisExtentTransByGridRect(axis, gridXY, gridWH) {
var extent = [0, gridWH];
var idx = axis.inverse ? 1 : 0;
axis.setExtent(extent[idx], extent[1 - idx]);
updateAxisTransform(axis, gridXY);
}
var legacyLayOutGridByContainLabel;
export function registerLegacyGridContainLabelImpl(impl) {
legacyLayOutGridByContainLabel = impl;
}
// Return noPxChange.
function layOutGridByOuterBounds(outerBoundsRect, outerBoundsContain, outerBoundsClamp, gridRect, axesMap, axisBuilderSharedCtx, layoutRef) {
if (process.env.NODE_ENV !== 'production') {
assert(outerBoundsContain === 'all' || outerBoundsContain === 'axisLabel');
}
// Assume `updateAllAxisExtentTransByGridRect` has been performed once before this call.
// [NOTE]:
// - The bounding rect of the axis elements might be sensitve to variations in `axis.extent` due to strategies
// like hideOverlap/moveOverlap. @see the comment in `LabelLayoutBase['suggestIgnore']`.
// - The final `gridRect` might be slightly smaller than the ideally expected result if labels are giant and
// get hidden due to overlapping. More iterations could improve precision, but not performant. We consider
// the current result acceptable, since no alignment among charts can be guaranteed when using this feature.
createOrUpdateAxesView(gridRect, axesMap, AxisTickLabelComputingKind.estimate, outerBoundsContain, false, layoutRef);
var margin = [0, 0, 0, 0];
fillLabelNameOverflowOnOneDimension(0);
fillLabelNameOverflowOnOneDimension(1);
// If axis is blank, no label can be used to detect overflow.
// gridRect itself should not overflow.
fillMarginOnOneDimension(gridRect, 0, NaN);
fillMarginOnOneDimension(gridRect, 1, NaN);
var noPxChange = find(margin, function (item) {
return item > 0;
}) == null;
expandOrShrinkRect(gridRect, margin, true, true, outerBoundsClamp);
updateAllAxisExtentTransByGridRect(axesMap, gridRect);
return noPxChange;
function fillLabelNameOverflowOnOneDimension(xyIdx) {
each(axesMap[XY[xyIdx]], function (axis) {
if (!shouldAxisShow(axis.model)) {
return;
}
// FIXME: zr Group.union may wrongly union (0, 0, 0, 0) and not performant.
// unionRect.union(axis.axisBuilder.group.getBoundingRect());
// If ussing Group.getBoundingRect to calculate shrink space, it is not strictly accurate when
// the outermost label is ignored and the secondary label is very long and contribute to the
// union extension:
// -|---|---|---|
// 1,000,000,000
// Therefore we calculate them one by one.
// Also considered axis may be blank or no labels.
var sharedRecord = axisBuilderSharedCtx.ensureRecord(axis.model);
var labelInfoList = sharedRecord.labelInfoList;
if (labelInfoList) {
for (var idx = 0; idx < labelInfoList.length; idx++) {
var labelInfo = labelInfoList[idx];
var proportion = axis.scale.normalize(getTickValueOutermost(axis.scale, getLabelInner(labelInfo.label).labelInfo.tick));
proportion = xyIdx === 1 ? 1 - proportion : proportion;
// xAxis use proportion on x, yAxis use proprotion on y, otherwise not.
fillMarginOnOneDimension(labelInfo.rect, xyIdx, proportion);
fillMarginOnOneDimension(labelInfo.rect, 1 - xyIdx, NaN);
}
}
var nameLayout = sharedRecord.nameLayout;
if (nameLayout) {
var proportion = isNameLocationCenter(sharedRecord.nameLocation) ? 0.5 : NaN;
fillMarginOnOneDimension(nameLayout.rect, xyIdx, proportion);
fillMarginOnOneDimension(nameLayout.rect, 1 - xyIdx, NaN);
}
});
}
function fillMarginOnOneDimension(itemRect, xyIdx, proportion // NaN mean no use proportion
) {
var overflow1 = outerBoundsRect[XY[xyIdx]] - itemRect[XY[xyIdx]];
var overflow2 = itemRect[WH[xyIdx]] + itemRect[XY[xyIdx]] - (outerBoundsRect[WH[xyIdx]] + outerBoundsRect[XY[xyIdx]]);
overflow1 = applyProportion(overflow1, 1 - proportion);
overflow2 = applyProportion(overflow2, proportion);
var minIdx = XY_TO_MARGIN_IDX[xyIdx][0];
var maxIdx = XY_TO_MARGIN_IDX[xyIdx][1];
margin[minIdx] = mathMax(margin[minIdx], overflow1);
margin[maxIdx] = mathMax(margin[maxIdx], overflow2);
}
function applyProportion(overflow, proportion) {
// proportion is not likely to near zero. If so, give up shrink
if (overflow > 0 && !eqNaN(proportion) && proportion > 1e-4) {
overflow /= proportion;
}
return overflow;
}
}
function createAxisBiulders(gridRect, cartesians, axesMap, optionContainLabel, api) {
var axisBuilderSharedCtx = new AxisBuilderSharedContext(resolveAxisNameOverlapForGrid);
each(axesMap, function (axisList) {
return each(axisList, function (axis) {
if (shouldAxisShow(axis.model)) {
// See `AxisBaseOptionCommon['nameMoveOverlap']`.
var defaultNameMoveOverlap = !optionContainLabel;
axis.axisBuilder = createCartesianAxisViewCommonPartBuilder(gridRect, cartesians, axis.model, api, axisBuilderSharedCtx, defaultNameMoveOverlap);
}
});
});
return axisBuilderSharedCtx;
}
/**
* Promote the axis-elements-building from "view render" stage to "coordinate system resize" stage.
* This is aimed to resovle overlap across multiple axes, since currently it's hard to reconcile
* multiple axes in "view render" stage.
*
* [CAUTION] But this promotion assumes that the subsequent "visual mapping" stage does not affect
* this axis-elements-building; otherwise we have to refactor it again.
*/
function createOrUpdateAxesView(gridRect, axesMap, kind, outerBoundsContain, noPxChange, layoutRef) {
var isDetermine = kind === AxisTickLabelComputingKind.determine;
each(axesMap, function (axisList) {
return each(axisList, function (axis) {
if (shouldAxisShow(axis.model)) {
updateCartesianAxisViewCommonPartBuilder(axis.axisBuilder, gridRect, axis.model);
axis.axisBuilder.build(isDetermine ? {
axisTickLabelDetermine: true
} : {
axisTickLabelEstimate: true
}, {
noPxChange: noPxChange
});
}
});
});
var nameMarginLevelMap = {
x: 0,
y: 0
};
calcNameMarginLevel(0);
calcNameMarginLevel(1);
function calcNameMarginLevel(xyIdx) {
nameMarginLevelMap[XY[1 - xyIdx]] = gridRect[WH[xyIdx]] <= layoutRef.refContainer[WH[xyIdx]] * 0.5 ? 0 : 1 - xyIdx === 1 ? 2 : 1;
}
each(axesMap, function (axisList, xy) {
return each(axisList, function (axis) {
if (shouldAxisShow(axis.model)) {
if (outerBoundsContain === 'all' || isDetermine) {
// To resolve overlap, `axisName` layout depends on `axisTickLabel` layout result
// (all of the axes of the same `grid`; consider multiple x or y axes).
axis.axisBuilder.build({
axisName: true
}, {
nameMarginLevel: nameMarginLevelMap[xy]
});
}
if (isDetermine) {
axis.axisBuilder.build({
axisLine: true
});
}
}
});
});
}
function prepareOuterBounds(gridModel, rawGridRect, layoutRef) {
var outerBoundsRect;
var optionOuterBoundsMode = gridModel.get('outerBoundsMode', true);
if (optionOuterBoundsMode === 'same') {
outerBoundsRect = rawGridRect.clone();
} else if (optionOuterBoundsMode == null || optionOuterBoundsMode === 'auto') {
outerBoundsRect = getLayoutRect(gridModel.get('outerBounds', true) || OUTER_BOUNDS_DEFAULT, layoutRef.refContainer);
} else if (optionOuterBoundsMode !== 'none') {
if (process.env.NODE_ENV !== 'production') {
error("Invalid grid[" + gridModel.componentIndex + "].outerBoundsMode.");
}
}
var optionOuterBoundsContain = gridModel.get('outerBoundsContain', true);
var parsedOuterBoundsContain;
if (optionOuterBoundsContain == null || optionOuterBoundsContain === 'auto') {
parsedOuterBoundsContain = 'all';
} else if (indexOf(['all', 'axisLabel'], optionOuterBoundsContain) < 0) {
if (process.env.NODE_ENV !== 'production') {
error("Invalid grid[" + gridModel.componentIndex + "].outerBoundsContain.");
}
parsedOuterBoundsContain = 'all';
} else {
parsedOuterBoundsContain = optionOuterBoundsContain;
}
var outerBoundsClamp = [parsePositionSizeOption(retrieve2(gridModel.get('outerBoundsClampWidth', true), OUTER_BOUNDS_CLAMP_DEFAULT[0]), rawGridRect.width), parsePositionSizeOption(retrieve2(gridModel.get('outerBoundsClampHeight', true), OUTER_BOUNDS_CLAMP_DEFAULT[1]), rawGridRect.height)];
return {
outerBoundsRect: outerBoundsRect,
parsedOuterBoundsContain: parsedOuterBoundsContain,
outerBoundsClamp: outerBoundsClamp
};
}
var resolveAxisNameOverlapForGrid = function (cfg, ctx, axisModel, nameLayoutInfo, nameMoveDirVec, thisRecord) {
var perpendicularDim = axisModel.axis.dim === 'x' ? 'y' : 'x';
resolveAxisNameOverlapDefault(cfg, ctx, axisModel, nameLayoutInfo, nameMoveDirVec, thisRecord);
// If nameLocation 'center', and there are multiple axes parallel to this axis, do not adjust by
// other axes, because the axis name should be close to its axis line as much as possible even
// if overlapping; otherwise it might cause misleading.
// If nameLocation 'center', do not adjust by perpendicular axes, since they are not likely to overlap.
// If nameLocation 'start'/'end', move name within the same direction to escape overlap with the
// perpendicular axes.
if (!isNameLocationCenter(cfg.nameLocation)) {
each(ctx.recordMap[perpendicularDim], function (perpenRecord) {
// perpendicular axis may be no name.
if (perpenRecord && perpenRecord.labelInfoList && perpenRecord.dirVec) {
moveIfOverlapByLinearLabels(perpenRecord.labelInfoList, perpenRecord.dirVec, nameLayoutInfo, nameMoveDirVec);
}
});
}
};
export default Grid;
+102
View File
@@ -0,0 +1,102 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import ComponentModel from '../../model/Component.js';
import { getLayoutParams, mergeLayoutParam } from '../../util/layout.js';
import tokens from '../../visual/tokens.js';
// For backward compatibility, do not use a margin. Although the labels might touch the edge of
// the canvas, the chart canvas probably does not have an border or a different background color within a page.
export var OUTER_BOUNDS_DEFAULT = {
left: 0,
right: 0,
top: 0,
bottom: 0
};
export var OUTER_BOUNDS_CLAMP_DEFAULT = ['25%', '25%'];
export var COORD_SYS_TYPE_CARTESIAN_2D = 'cartesian2d';
var GridModel = /** @class */function (_super) {
__extends(GridModel, _super);
function GridModel() {
return _super !== null && _super.apply(this, arguments) || this;
}
GridModel.prototype.mergeDefaultAndTheme = function (option, ecModel) {
var outerBoundsCp = getLayoutParams(option.outerBounds);
_super.prototype.mergeDefaultAndTheme.apply(this, arguments);
if (outerBoundsCp && option.outerBounds) {
mergeLayoutParam(option.outerBounds, outerBoundsCp);
}
};
GridModel.prototype.mergeOption = function (newOption, ecModel) {
_super.prototype.mergeOption.apply(this, arguments);
if (this.option.outerBounds && newOption.outerBounds) {
mergeLayoutParam(this.option.outerBounds, newOption.outerBounds);
}
};
GridModel.type = 'grid';
GridModel.dependencies = ['xAxis', 'yAxis'];
GridModel.layoutMode = 'box';
GridModel.defaultOption = {
show: false,
// zlevel: 0,
z: 0,
left: '15%',
top: 65,
right: '10%',
bottom: 80,
// If grid size contain label
containLabel: false,
outerBoundsMode: 'auto',
outerBounds: OUTER_BOUNDS_DEFAULT,
outerBoundsContain: 'all',
outerBoundsClampWidth: OUTER_BOUNDS_CLAMP_DEFAULT[0],
outerBoundsClampHeight: OUTER_BOUNDS_CLAMP_DEFAULT[1],
// width: {totalWidth} - left - right,
// height: {totalHeight} - top - bottom,
backgroundColor: tokens.color.transparent,
borderWidth: 1,
borderColor: tokens.color.neutral30
};
return GridModel;
}(ComponentModel);
export default GridModel;
+169
View File
@@ -0,0 +1,169 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import { SINGLE_REFERRING } from '../../util/model.js';
import AxisBuilder from '../../component/axis/AxisBuilder.js';
import { isIntervalOrLogScale } from '../../scale/helper.js';
/**
* [__CAUTION__]
* MUST guarantee: if only the input `rect` and `axis.extent` changed,
* only `layout.position` changes.
* This character is replied on `grid.contain` calculation in `AxisBuilder`.
* @see updateCartesianAxisViewCommonPartBuilder
*
* Can only be called after coordinate system creation stage.
* (Can be called before coordinate system update stage).
*/
export function layout(rect, axisModel, opt) {
opt = opt || {};
var axis = axisModel.axis;
var layout = {};
var otherAxisOnZeroOf = axis.getAxesOnZeroOf()[0];
var rawAxisPosition = axis.position;
var axisPosition = otherAxisOnZeroOf ? 'onZero' : rawAxisPosition;
var axisDim = axis.dim;
var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height];
var idx = {
left: 0,
right: 1,
top: 0,
bottom: 1,
onZero: 2
};
var axisOffset = axisModel.get('offset') || 0;
var posBound = axisDim === 'x' ? [rectBound[2] - axisOffset, rectBound[3] + axisOffset] : [rectBound[0] - axisOffset, rectBound[1] + axisOffset];
if (otherAxisOnZeroOf) {
var onZeroCoord = otherAxisOnZeroOf.toGlobalCoord(otherAxisOnZeroOf.dataToCoord(0));
posBound[idx.onZero] = Math.max(Math.min(onZeroCoord, posBound[1]), posBound[0]);
}
// Axis position
layout.position = [axisDim === 'y' ? posBound[idx[axisPosition]] : rectBound[0], axisDim === 'x' ? posBound[idx[axisPosition]] : rectBound[3]];
// Axis rotation
layout.rotation = Math.PI / 2 * (axisDim === 'x' ? 0 : 1);
// Tick and label direction, x y is axisDim
var dirMap = {
top: -1,
bottom: 1,
left: -1,
right: 1
};
layout.labelDirection = layout.tickDirection = layout.nameDirection = dirMap[rawAxisPosition];
layout.labelOffset = otherAxisOnZeroOf ? posBound[idx[rawAxisPosition]] - posBound[idx.onZero] : 0;
if (axisModel.get(['axisTick', 'inside'])) {
layout.tickDirection = -layout.tickDirection;
}
if (zrUtil.retrieve(opt.labelInside, axisModel.get(['axisLabel', 'inside']))) {
layout.labelDirection = -layout.labelDirection;
}
// Special label rotation
var labelRotate = axisModel.get(['axisLabel', 'rotate']);
layout.labelRotate = axisPosition === 'top' ? -labelRotate : labelRotate;
// Over splitLine and splitArea
layout.z2 = 1;
return layout;
}
export function isCartesian2DDeclaredSeries(seriesModel) {
return seriesModel.get('coordinateSystem') === 'cartesian2d';
}
/**
* Note: If pie (or other similar series) use cartesian2d, here
* option `seriesModel.get('coordinateSystem') === 'cartesian2d'`
* and `seriesModel.coordinateSystem !== cartesian2dCoordSysInstance`
* and `seriesModel.boxCoordinateSystem === cartesian2dCoordSysInstance`,
* the logic below is probably wrong, therefore skip it temporarily.
*/
export function isCartesian2DInjectedAsDataCoordSys(seriesModel) {
return seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d';
}
export function findAxisModels(seriesModel) {
var axisModelMap = {
xAxisModel: null,
yAxisModel: null
};
zrUtil.each(axisModelMap, function (v, key) {
var axisType = key.replace(/Model$/, '');
var axisModel = seriesModel.getReferringComponents(axisType, SINGLE_REFERRING).models[0];
if (process.env.NODE_ENV !== 'production') {
if (!axisModel) {
throw new Error(axisType + ' "' + zrUtil.retrieve3(seriesModel.get(axisType + 'Index'), seriesModel.get(axisType + 'Id'), 0) + '" not found');
}
}
axisModelMap[key] = axisModel;
});
return axisModelMap;
}
export function createCartesianAxisViewCommonPartBuilder(gridRect, cartesians, axisModel, api, ctx, defaultNameMoveOverlap) {
var layoutResult = layout(gridRect, axisModel);
var axisLineAutoShow = false;
var axisTickAutoShow = false;
// Not show axisTick or axisLine if other axis is category / time
for (var i = 0; i < cartesians.length; i++) {
if (isIntervalOrLogScale(cartesians[i].getOtherAxis(axisModel.axis).scale)) {
// Still show axis tick or axisLine if other axis is value / log
axisLineAutoShow = axisTickAutoShow = true;
if (axisModel.axis.type === 'category' && axisModel.axis.onBand) {
axisTickAutoShow = false;
}
}
}
layoutResult.axisLineAutoShow = axisLineAutoShow;
layoutResult.axisTickAutoShow = axisTickAutoShow;
layoutResult.defaultNameMoveOverlap = defaultNameMoveOverlap;
return new AxisBuilder(axisModel, api, layoutResult, ctx);
}
export function updateCartesianAxisViewCommonPartBuilder(axisBuilder, gridRect, axisModel) {
var newRaw = layout(gridRect, axisModel);
if (process.env.NODE_ENV !== 'production') {
var oldRaw_1 = axisBuilder.__getRawCfg();
zrUtil.each(zrUtil.keys(newRaw), function (prop) {
if (prop !== 'position' && prop !== 'labelOffset') {
zrUtil.assert(newRaw[prop] === oldRaw_1[prop]);
}
});
}
axisBuilder.updateCfg(newRaw);
}
export function getCartesianAxisHashKey(axis) {
return axis.dim + '_' + axis.index;
}
+291
View File
@@ -0,0 +1,291 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// import * as echarts from '../../core/echarts.js';
// import { createHashMap, each, HashMap, hasOwn, keys, map } from 'zrender/lib/core/util.js';
// import SeriesModel from '../../model/Series.js';
// import {
// isCartesian2DDeclaredSeries, findAxisModels, isCartesian2DInjectedAsDataCoordSys
// } from './cartesianAxisHelper.js';
// import { getDataDimensionsOnAxis } from '../axisHelper.js';
// import { AxisBaseModel } from '../AxisBaseModel.js';
// import type Axis from '../Axis.js';
// import GlobalModel from '../../model/Global.js';
// import { Dictionary } from '../../util/types.js';
// import {
// AXIS_EXTENT_INFO_BUILD_FROM_DATA_ZOOM, ensureScaleRawExtentInfo, ScaleRawExtentInfo, ScaleRawExtentResult
// } from '../scaleRawExtentInfo.js';
// import { initExtentForUnion, unionExtentFromNumber } from '../../util/model.js';
/**
* @obsolete
* PENDING:
* - This file is not used anywhere currently.
* - This is a similar behavior to `dataZoom`, but historically supported separately.
* Can it be merged into `dataZoom`?
* - The impl need to be fixed, @see #15050 , and,
* - Remove side-effect.
* - Need to fix the case:
* series_a =>
* x_m (category): dataExtent: [3,8]
* y_i:
* series_b =>
* x_m (category): dataExtent: [4,6]
* y_j:
* series_c =>
* x_m (category): dataExtent: [5,7]
* y_j:
* dataZoom control y_i, so series_a is excluded.
* So x_m.condExtent = [4,6] U [5,7] = [4,7] , and use it to call ensureScaleRawExtentInfo.
* (incorrect?, supposed to be [3,8]?)
*
* See test case `test/axis-filter-extent.html`.
*
* The responsibility of this processor:
* Enable category axis to use the specified `min`/`max` to shrink the extent of the orthogonal axis in
* Cartesian2D. That is, if some data item on a category axis is out of the range of `min`/`max`, the
* extent of the orthogonal axis will exclude the data items.
* A typical case is bar-racing, where bars are sorted dynamically and may only need to
* displayed part of the whole bars.
*
* IMPL_MEMO:
* - For each triple xAxis-yAxis-series, if either xAxis or yAxis is controlled by a dataZoom,
* the triple should be ignored in this processor.
* - Input:
* - Cartesian series data ("series approximate extent" has been prepared).
* - Axis original `ScaleRawExtentInfo`
* (the content comes from ec option and "series approximate extent").
* - Modify(result):
* - `ScaleRawExtentInfo#min/max` of the determined "target axis".
* - "series approximate extent".
*/
// The priority is just after dataZoom processor.
// echarts.registerProcessor(echarts.PRIORITY.PROCESSOR.FILTER + 10, {
// getTargetSeries: function (ecModel) {
// const seriesModelMap = createHashMap<SeriesModel>();
// ecModel.eachSeries(function (seriesModel: SeriesModel) {
// isCartesian2DDeclaredSeries(seriesModel) && seriesModelMap.set(seriesModel.uid, seriesModel);
// });
// return seriesModelMap;
// },
// overallReset: function (ecModel, api) {
// const seriesRecords = [] as SeriesRecord[];
// const axisRecordMap = createHashMap<AxisRecord>();
// prepareDataExtentOnAxis(ecModel, axisRecordMap, seriesRecords);
// calculateFilteredExtent(axisRecordMap, seriesRecords);
// shrinkAxisExtent(axisRecordMap);
// }
// });
// type AxisRecord = {
// rawExtentInfo?: ScaleRawExtentInfo;
// rawExtentResult?: ScaleRawExtentResult;
// tarExtent?: number[];
// };
// type SeriesRecord = {
// seriesModel: SeriesModel;
// xAxisModel: AxisBaseModel;
// yAxisModel: AxisBaseModel;
// };
// function prepareDataExtentOnAxis(
// ecModel: GlobalModel,
// axisRecordMap: HashMap<AxisRecord>,
// seriesRecords: SeriesRecord[]
// ): void {
// ecModel.eachSeries(function (seriesModel: SeriesModel) {
// // If pie (or other similar series) use cartesian2d, the logic below is
// // probably wrong, therefore skip it temporarily.
// // TODO: support union extent in this case.
// // e.g. make a fake seriesData by series.coord/series.center, and it can be
// // performed by data processing (such as, filter), and applied here.
// if (!isCartesian2DInjectedAsDataCoordSys(seriesModel)) {
// return;
// }
// const axesModelMap = findAxisModels(seriesModel);
// const xAxisModel = axesModelMap.xAxisModel;
// const yAxisModel = axesModelMap.yAxisModel;
// const xAxis = xAxisModel.axis;
// const yAxis = yAxisModel.axis;
// const xRawExtentInfo = ensureScaleRawExtentInfo(xAxis);
// const yRawExtentInfo = ensureScaleRawExtentInfo(yAxis);
// // If either axis controlled by other filter like "dataZoom",
// // use the rule of dataZoom rather than adopting the rules here.
// if (
// (xRawExtentInfo && xRawExtentInfo.from === AXIS_EXTENT_INFO_BUILD_FROM_DATA_ZOOM)
// || (yRawExtentInfo && yRawExtentInfo.from === AXIS_EXTENT_INFO_BUILD_FROM_DATA_ZOOM)
// ) {
// return;
// }
// seriesRecords.push({
// seriesModel: seriesModel,
// xAxisModel: xAxisModel,
// yAxisModel: yAxisModel
// });
// });
// }
// function calculateFilteredExtent(
// axisRecordMap: HashMap<AxisRecord>,
// seriesRecords: SeriesRecord[]
// ) {
// each(seriesRecords, function (seriesRecord) {
// const xAxisModel = seriesRecord.xAxisModel;
// const yAxisModel = seriesRecord.yAxisModel;
// const xAxis = xAxisModel.axis;
// const yAxis = yAxisModel.axis;
// const xAxisRecord = prepareAxisRecord(axisRecordMap, xAxisModel);
// const yAxisRecord = prepareAxisRecord(axisRecordMap, yAxisModel);
// xAxisRecord.rawExtentInfo = ensureScaleRawExtentInfo(xAxis);
// yAxisRecord.rawExtentInfo = ensureScaleRawExtentInfo(yAxis);
// xAxisRecord.rawExtentResult = xAxisRecord.rawExtentInfo.calculate();
// yAxisRecord.rawExtentResult = yAxisRecord.rawExtentInfo.calculate();
// const data = seriesRecord.seriesModel.getData();
// // For duplication removal.
// // key: series data dimension corresponding to the condition axis.
// const condDimMap: Dictionary<boolean> = {};
// // key: series data dimension corresponding to the target axis.
// const tarDimMap: Dictionary<boolean> = {};
// let condAxis: Axis;
// let tarAxisRecord: AxisRecord;
// function addCondition(axis: Axis, axisRecord: AxisRecord) {
// // But for simplicity and safety and performance, we only adopt this
// // feature on category axis at present.
// const rawExtentResult = axisRecord.rawExtentResult;
// if (axis.type === 'category'
// && (rawExtentResult.dataMinMax[0] < rawExtentResult.resultMinMax[0]
// || rawExtentResult.resultMinMax[1] < rawExtentResult.dataMinMax[1]
// )
// ) {
// each(getDataDimensionsOnAxis(data, axis.dim), function (dataDim) {
// if (!hasOwn(condDimMap, dataDim)) {
// condDimMap[dataDim] = true;
// condAxis = axis;
// }
// });
// }
// }
// function addTarget(axis: Axis, axisRecord: AxisRecord) {
// const rawExtentResult = axisRecord.rawExtentResult;
// const fixMinMax = rawExtentResult.fixMinMax;
// if (axis.type !== 'category'
// && (!fixMinMax[0] || !fixMinMax[1])
// ) {
// each(getDataDimensionsOnAxis(data, axis.dim), function (dataDim) {
// if (!hasOwn(condDimMap, dataDim) && !hasOwn(tarDimMap, dataDim)) {
// tarDimMap[dataDim] = true;
// tarAxisRecord = axisRecord;
// }
// });
// }
// }
// addCondition(xAxis, xAxisRecord);
// addCondition(yAxis, yAxisRecord);
// addTarget(xAxis, xAxisRecord);
// addTarget(yAxis, yAxisRecord);
// const condDims = keys(condDimMap);
// const tarDims = keys(tarDimMap);
// const tarDimExtents = map(tarDims, function () {
// return initExtentForUnion();
// });
// const condDimsLen = condDims.length;
// const tarDimsLen = tarDims.length;
// if (!condDimsLen || !tarDimsLen) {
// return;
// }
// const singleCondDim = condDimsLen === 1 ? condDims[0] : null;
// const singleTarDim = tarDimsLen === 1 ? tarDims[0] : null;
// const dataLen = data.count();
// // Time consuming, because this is a "block task".
// // Simple optimization for the vast majority of cases.
// if (singleCondDim && singleTarDim) {
// for (let dataIdx = 0; dataIdx < dataLen; dataIdx++) {
// const condVal = data.get(singleCondDim, dataIdx) as number;
// if (condAxis.scale.contain(condVal)) {
// unionExtentFromNumber(tarDimExtents[0], data.get(singleTarDim, dataIdx) as number);
// }
// }
// }
// else {
// for (let dataIdx = 0; dataIdx < dataLen; dataIdx++) {
// for (let j = 0; j < condDimsLen; j++) {
// const condVal = data.get(condDims[j], dataIdx) as number;
// if (condAxis.scale.contain(condVal)) {
// for (let k = 0; k < tarDimsLen; k++) {
// unionExtentFromNumber(tarDimExtents[k], data.get(tarDims[k], dataIdx) as number);
// }
// // Any one dim is in range means satisfied.
// break;
// }
// }
// }
// }
// each(tarDimExtents, function (tarDimExtent, i) {
// // FIXME: if there has been approximateExtent set?
// data.setApproximateExtent(tarDimExtent as [number, number], tarDims[i]);
// const tarAxisExtent = tarAxisRecord.tarExtent = tarAxisRecord.tarExtent || initExtentForUnion();
// unionExtentFromNumber(tarAxisExtent, tarDimExtent[0]);
// unionExtentFromNumber(tarAxisExtent, tarDimExtent[1]);
// });
// });
// }
// function shrinkAxisExtent(axisRecordMap: HashMap<AxisRecord>) {
// axisRecordMap.each(function (axisRecord) {
// const tarAxisExtent = axisRecord.tarExtent;
// if (tarAxisExtent) {
// const rawExtentResult = axisRecord.rawExtentResult;
// const fixMinMax = rawExtentResult.fixMinMax;
// // const rawExtentInfo = axisRecord.rawExtentInfo;
// // Shrink the original extent.
// if (!fixMinMax[0] && tarAxisExtent[0] > rawExtentResult.resultMinMax[0]) {
// // rawExtentInfo.modifyDataMinMax('min', tarAxisExtent[0]);
// }
// if (!fixMinMax[1] && tarAxisExtent[1] < rawExtentResult.resultMinMax[1]) {
// // rawExtentInfo.modifyDataMinMax('max', tarAxisExtent[1]);
// }
// }
// });
// }
// function prepareAxisRecord(
// axisRecordMap: HashMap<AxisRecord>,
// axisModel: AxisBaseModel
// ): AxisRecord {
// return axisRecordMap.get(axisModel.uid)
// || axisRecordMap.set(axisModel.uid, {});
// }
+121
View File
@@ -0,0 +1,121 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import BoundingRect from 'zrender/lib/core/BoundingRect.js';
import { each } from 'zrender/lib/core/util.js';
import { registerLegacyGridContainLabelImpl } from './Grid.js';
import OrdinalScale from '../../scale/Ordinal.js';
import { makeLabelFormatter } from '../axisHelper.js';
/**
* [CAUTION] Never export methods other than `installLegacyGridContainLabel`.
*/
export function installLegacyGridContainLabel() {
registerLegacyGridContainLabelImpl(legacyLayOutGridByContained);
}
/**
* The input gridRect and axes will be modified.
*/
function legacyLayOutGridByContained(axesList, gridRect) {
each(axesList, function (axis) {
if (!axis.model.get(['axisLabel', 'inside'])) {
var labelUnionRect = estimateLabelUnionRect(axis);
if (labelUnionRect) {
var dim = axis.isHorizontal() ? 'height' : 'width';
var margin = axis.model.get(['axisLabel', 'margin']);
gridRect[dim] -= labelUnionRect[dim] + margin;
if (axis.position === 'top') {
gridRect.y += labelUnionRect.height + margin;
} else if (axis.position === 'left') {
gridRect.x += labelUnionRect.width + margin;
}
}
}
});
}
/**
* @return Be null/undefined if no labels.
*/
function estimateLabelUnionRect(axis) {
var axisModel = axis.model;
var scale = axis.scale;
if (!axisModel.get(['axisLabel', 'show']) || scale.isBlank()) {
return;
}
var realNumberScaleTicks;
var tickCount;
var categoryScaleExtent = scale.getExtent();
// Optimize for large category data, avoid call `getTicks()`.
if (scale instanceof OrdinalScale) {
tickCount = scale.count();
} else {
realNumberScaleTicks = scale.getTicks();
tickCount = realNumberScaleTicks.length;
}
var axisLabelModel = axis.getLabelModel();
var labelFormatter = makeLabelFormatter(axis);
var rect;
var step = 1;
// Simple optimization for large amount of category labels
if (tickCount > 40) {
step = Math.ceil(tickCount / 40);
}
for (var i = 0; i < tickCount; i += step) {
var tick = realNumberScaleTicks ? realNumberScaleTicks[i] : {
value: categoryScaleExtent[0] + i
};
var label = labelFormatter(tick, i);
var unrotatedSingleRect = axisLabelModel.getTextRect(label);
var singleRect = rotateTextRect(unrotatedSingleRect, axisLabelModel.get('rotate') || 0);
rect ? rect.union(singleRect) : rect = singleRect;
}
return rect;
function rotateTextRect(textRect, rotate) {
var rotateRadians = rotate * Math.PI / 180;
var beforeWidth = textRect.width;
var beforeHeight = textRect.height;
var afterWidth = beforeWidth * Math.abs(Math.cos(rotateRadians)) + Math.abs(beforeHeight * Math.sin(rotateRadians));
var afterHeight = beforeWidth * Math.abs(Math.sin(rotateRadians)) + Math.abs(beforeHeight * Math.cos(rotateRadians));
var rotatedRect = new BoundingRect(textRect.x, textRect.y, afterWidth, afterHeight);
return rotatedRect;
}
}
+75
View File
@@ -0,0 +1,75 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import { calcBandWidth } from '../axisBand.js';
function dataToCoordSize(dataSize, dataItem) {
// dataItem is necessary in log axis.
dataItem = dataItem || [0, 0];
return zrUtil.map(['x', 'y'], function (dim, dimIdx) {
var axis = this.getAxis(dim);
var val = dataItem[dimIdx];
var halfSize = dataSize[dimIdx] / 2;
return axis.type === 'category' ? calcBandWidth(axis).w : Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize));
}, this);
}
export default function cartesianPrepareCustom(coordSys) {
var rect = coordSys.master.getRect();
return {
coordSys: {
// The name exposed to user is always 'cartesian2d' but not 'grid'.
type: 'cartesian2d',
x: rect.x,
y: rect.y,
width: rect.width,
height: rect.height
},
api: {
coord: function (data) {
// do not provide "out" param
return coordSys.dataToPoint(data);
},
size: zrUtil.bind(dataToCoordSize, coordSys)
}
};
}