@antv/f2
Version:
Charts for mobile visualization.
274 lines • 8.74 kB
JavaScript
import { __assign, __extends } from "tslib";
import { jsx, isEqual, Component } from '@antv/f-engine';
import { deepMix, isFunction, mix, each, clone, isString, isNumber, isArray, isNil } from '@antv/util';
export default (function (View) {
return /** @class */function (_super) {
__extends(Axis, _super);
function Axis(props) {
var _this = _super.call(this, props) || this;
_this.axisStyle = {};
var chart = props.chart,
field = props.field;
var scaleOption = _this.getScaleOption(props);
chart.setScale(field, scaleOption);
return _this;
}
Axis.prototype.willReceiveProps = function (nextProps) {
var lastProps = this.props;
var chart = nextProps.chart,
field = nextProps.field;
var nextScaleOption = this.getScaleOption(nextProps);
var lastScaleOption = this.getScaleOption(lastProps);
if (!isEqual(nextScaleOption, lastScaleOption)) {
chart.setScale(field, nextScaleOption);
}
};
Axis.prototype.willMount = function () {
this.updateCoord();
};
Axis.prototype.willUpdate = function () {
this.updateCoord();
};
Axis.prototype.getScaleOption = function (props) {
var type = props.type,
tickCount = props.tickCount,
range = props.range,
mask = props.mask,
formatter = props.formatter,
ticks = props.ticks,
min = props.min,
max = props.max,
nice = props.nice;
return {
type: type,
tickCount: tickCount,
range: range,
mask: mask,
formatter: formatter,
min: min,
max: max,
nice: nice,
ticks: ticks
};
};
Axis.prototype._getDimType = function () {
var props = this.props;
var field = props.field,
chart = props.chart;
var xScales = chart.getXScales();
var scales = xScales.filter(function (scale) {
return scale.field === field;
});
return scales.length > 0 ? 'x' : 'y';
};
// 获取ticks最大的宽高
Axis.prototype.getMaxBBox = function (ticks, style) {
var context = this.context;
var measureText = context.measureText;
var label = style.label,
labelOffset = style.labelOffset;
var width = 0;
var height = 0;
ticks.forEach(function (tick) {
if (!label) return;
var _a = tick.labelStyle,
labelStyle = _a === void 0 ? {} : _a,
text = tick.text;
var bbox = measureText(labelStyle.text || text, __assign(__assign({}, label), labelStyle));
width = Math.max(width, bbox.width);
height = Math.max(height, bbox.height);
});
if (!width && !height) {
return {
width: width,
height: height
};
}
var bbox = {
width: width + labelOffset,
height: height + labelOffset
};
return bbox;
};
Axis.prototype._getPosition = function () {
var props = this.props;
var position = props.position,
coord = props.coord;
if (position) {
return position;
}
var dimType = this._getDimType();
if (coord.transposed) {
return dimType === 'x' ? 'left' : 'bottom';
}
return dimType === 'x' ? 'bottom' : 'left';
};
Axis.prototype.getTicks = function () {
var props = this.props;
var field = props.field,
chart = props.chart;
var scale = chart.getScale(field);
var ticks = scale.getTicks();
// 设置tick的样式
ticks = this._setTicksStyle(ticks);
ticks = this._generateGridPoints(ticks);
return ticks;
};
/**
* 生成极坐标下网格线的交叉点
* @param ticks
* @returns
*/
Axis.prototype._generateGridPoints = function (ticks) {
var props = this.props;
var chart = props.chart,
coord = props.coord;
if (!coord.isPolar) {
return ticks;
}
var dimType = this._getDimType();
// 只需要在 y 的时候生成
if (dimType !== 'y') {
return ticks;
}
var xScale = chart.getXScales()[0];
var xTicks = xScale.getTicks();
ticks.forEach(function (tick) {
var gridPoints = xTicks.map(function (xTick) {
return coord.convertPoint({
x: xTick.value,
y: tick.value
});
});
// 添加第 1 个点,形成环状
gridPoints.push(gridPoints[0]);
tick.gridPoints = gridPoints;
});
return ticks;
};
Axis.prototype._setTicksStyle = function (ticks) {
var _this = this;
var _a = this,
props = _a.props,
context = _a.context;
var theme = context.theme,
px2hd = context.px2hd;
var _b = props.style,
style = _b === void 0 ? {} : _b;
var themeAxis = theme.axis;
each(themeAxis, function (value, key) {
// 关闭tick的样式
if (style[key] === null) {
return;
}
var styleValue = isFunction(style[key]) ? undefined : style[key];
if (isString(value) || isNumber(value)) {
_this.axisStyle[key] = px2hd(styleValue) || value;
} else if (isArray(styleValue)) {
_this.axisStyle[key] = styleValue.map(function (d) {
return px2hd(deepMix(clone(value), d));
});
} else {
_this.axisStyle[key] = px2hd(deepMix(clone(value), styleValue));
}
});
return ticks.map(function (tick, index) {
var label = style.label,
grid = style.grid;
var defaultLabelStyle = themeAxis.label,
defaultGridStyle = themeAxis.grid;
if (isFunction(label)) {
tick.labelStyle = px2hd(mix({}, defaultLabelStyle, label(tick.text, index, ticks)));
}
if (isFunction(grid)) {
tick.gridStyle = px2hd(mix({}, defaultGridStyle, grid(tick.text, index, ticks.length)));
}
return tick;
});
};
Axis.prototype.convertTicks = function (ticks) {
var props = this.props;
var coord = props.coord;
var dimType = this._getDimType();
var otherDim = dimType === 'x' ? 'y' : 'x';
return ticks.map(function (tick) {
var _a, _b;
var start = coord.convertPoint((_a = {}, _a[dimType] = tick.value, _a[otherDim] = 0, _a));
var end = coord.convertPoint((_b = {}, _b[dimType] = tick.value, _b[otherDim] = 1, _b));
return __assign(__assign({}, tick), {
points: [start, end]
});
});
};
Axis.prototype.measureLayout = function () {
var _a = this,
props = _a.props,
context = _a.context;
var visible = props.visible,
coord = props.coord,
style = props.style;
if (visible === false) {
return null;
}
var _b = style || {},
customWidth = _b.width,
customHeight = _b.height;
var ticks = this.getTicks();
var bbox = this.getMaxBBox(ticks, this.axisStyle);
var isPolar = coord.isPolar;
var dimType = this._getDimType();
// const { width, height } = bbox;
var width = isNil(customWidth) ? bbox.width : context.px2hd(customWidth);
var height = isNil(customHeight) ? bbox.height : context.px2hd(customHeight);
if (isPolar) {
// 机坐标系的 y 不占位置
if (dimType === 'y') {
return null;
}
// 4 个方向都需要留空
return ['top', 'right', 'bottom', 'left'].map(function (position) {
return {
position: position,
width: width,
height: height
};
});
}
// 直角坐标系下
var position = this._getPosition();
return {
position: position,
width: width,
height: height
};
};
// 主要是计算coord的布局
Axis.prototype.updateCoord = function () {
var props = this.props;
var chart = props.chart;
var layout = this.measureLayout();
chart.updateCoordFor(this, layout);
};
Axis.prototype.render = function () {
var _a = this,
props = _a.props,
axisStyle = _a.axisStyle;
var visible = props.visible,
coord = props.coord;
if (visible === false) {
return null;
}
var ticks = this.getTicks();
var position = this._getPosition();
var dimType = this._getDimType();
return jsx(View, __assign({}, props, {
style: axisStyle,
ticks: this.convertTicks(ticks),
coord: coord,
position: position,
dimType: dimType
}));
};
return Axis;
}(Component);
});