@visactor/vchart
Version:
charts lib based @visactor/VGrammar
306 lines (300 loc) • 16.5 kB
JavaScript
"use strict";
var __rest = this && this.__rest || function(s, e) {
var t = {};
for (var p in s) Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0 && (t[p] = s[p]);
if (null != s && "function" == typeof Object.getOwnPropertySymbols) {
var i = 0;
for (p = Object.getOwnPropertySymbols(s); i < p.length; i++) e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]) && (t[p[i]] = s[p[i]]);
}
return t;
};
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.PolarAxis = void 0;
const polar_1 = require("../../../constant/polar"), vscale_1 = require("@visactor/vscale"), layout_1 = require("../../../constant/layout"), type_1 = require("../../interface/type"), factory_1 = require("../../../core/factory"), model_1 = require("../../../util/model"), utils_1 = require("../../../series/util/utils"), util_1 = require("../util"), vutils_1 = require("@visactor/vutils"), base_axis_1 = require("../base-axis"), util_2 = require("./util"), vutils_extension_1 = require("@visactor/vutils-extension"), space_1 = require("../../../util/space");
class PolarAxis extends base_axis_1.AxisComponent {
get center() {
return this._center;
}
get startAngle() {
return this._startAngle;
}
get endAngle() {
return this._endAngle;
}
getOrient() {
return this._orient;
}
getDefaultInteractive() {
return "angle" !== this._orient;
}
getGroupScales() {
return this._groupScales;
}
static getSpecInfo(chartSpec) {
if (!chartSpec[this.specKey]) return null;
const isArraySpec = (0, vutils_1.isArray)(chartSpec[this.specKey]), axesSpec = isArraySpec ? chartSpec[this.specKey] : [ chartSpec[this.specKey] ], specInfos = [];
let angleAxisIndex, radiusAxisIndex;
const radiusAxisSpecInfos = [], angleAxisSpecInfos = [];
return axesSpec.forEach(((s, i) => {
if (!(0, util_1.isValidPolarAxis)(s)) return;
const {axisType: axisType, componentName: componentName, startAngle: startAngle, endAngle: endAngle, center: center, outerRadius: outerRadius, layoutRadius: layoutRadius} = (0,
util_2.getPolarAxisInfo)(s, chartSpec);
s.center = center, s.startAngle = startAngle, s.endAngle = endAngle, s.outerRadius = outerRadius,
s.type = axisType, s.layoutRadius = layoutRadius;
const info = {
spec: s,
specPath: isArraySpec ? [ this.specKey, i ] : [ this.specKey ],
specInfoPath: [ "component", this.specKey, i ],
type: componentName
};
specInfos.push(info), "radius" === s.orient ? (radiusAxisSpecInfos.push(info), radiusAxisIndex = i) : (angleAxisSpecInfos.push(info),
angleAxisIndex = i);
})), radiusAxisSpecInfos.forEach((info => {
info.angleAxisIndex = angleAxisIndex;
})), angleAxisSpecInfos.forEach((info => {
info.radiusAxisIndex = radiusAxisIndex;
})), specInfos;
}
static createComponent(specInfo, options) {
const {spec: spec} = specInfo, others = __rest(specInfo, [ "spec" ]), C = factory_1.Factory.getComponentInKey(others.type);
return C ? new C(spec, Object.assign(Object.assign({}, options), others)) : (options.onError(`Component ${others.type} not found`),
null);
}
constructor(spec, options) {
super(spec, options), this.type = type_1.ComponentTypeEnum.polarAxis, this.name = type_1.ComponentTypeEnum.polarAxis,
this._defaultBandPosition = 0, this._defaultBandInnerPadding = 0, this._defaultBandOuterPadding = 0,
this.layoutType = "absolute", this.layoutZIndex = layout_1.LayoutZIndex.Axis, this._tick = void 0,
this._center = null, this._startAngle = polar_1.POLAR_START_RADIAN, this._endAngle = polar_1.POLAR_END_RADIAN,
this._orient = "radius", this._groupScales = [], this.effect = {
scaleUpdate: param => {
this.computeData(null == param ? void 0 : param.value), (0, model_1.eachSeries)(this._regions, (s => {
"radius" === this.getOrient() ? (0, util_1.shouldUpdateAxis)(s.radiusAxisHelper, this.axisHelper(), (0,
vutils_1.isValid)(this._seriesUserId) || (0, vutils_1.isValid)(this._seriesIndex)) && (s.radiusAxisHelper = this.axisHelper()) : (0,
util_1.shouldUpdateAxis)(s.angleAxisHelper, this.axisHelper(), (0, vutils_1.isValid)(this._seriesUserId) || (0,
vutils_1.isValid)(this._seriesIndex)) && (s.angleAxisHelper = this.axisHelper());
}), {
userId: this._seriesUserId,
specIndex: this._seriesIndex
});
}
}, this._transformLayoutPosition = pos => {
var _a;
const region = null === (_a = this.getRegions()) || void 0 === _a ? void 0 : _a[0];
return region ? region.getLayoutStartPoint() : pos;
}, this.getCenter = () => {
var _a, _b;
const layoutRect = this.getRefLayoutRect(), {width: width, height: height} = layoutRect;
return {
x: (0, space_1.calcLayoutNumber)(null === (_a = this._center) || void 0 === _a ? void 0 : _a.x, width, layoutRect, width / 2),
y: (0, space_1.calcLayoutNumber)(null === (_b = this._center) || void 0 === _b ? void 0 : _b.y, height, layoutRect, height / 2)
};
}, this.getRefLayoutRect = () => this.getRegions()[0].getLayoutRect(), this._coordinateType = "polar";
}
setAttrFromSpec() {
super.setAttrFromSpec(), this.visible && (this._axisStyle = this._getAxisAttributes(),
this._gridStyle = this._getGridAttributes()), this._tick = this._spec.tick, this._orient = "angle" === this._spec.orient ? "angle" : "radius",
this._center = this._spec.center, this._startAngle = (0, vutils_1.degreeToRadian)(this._spec.startAngle),
this._endAngle = (0, vutils_1.degreeToRadian)(this._spec.endAngle), this._inverse = this._spec.inverse;
}
_tickTransformOption() {
var _a;
return Object.assign(Object.assign({}, super._tickTransformOption()), {
noDecimal: null === (_a = this._tick) || void 0 === _a ? void 0 : _a.noDecimals,
startAngle: this.startAngle,
labelOffset: (0, util_1.getAxisLabelOffset)(this._spec),
getRadius: () => this.getOuterRadius(),
inside: this._spec.inside
});
}
updateScaleRange() {
const prevRange = this._scale.range();
let newRange;
return newRange = "radius" === this.getOrient() ? this._inverse ? [ this.computeLayoutOuterRadius(), this.computeLayoutInnerRadius() ] : [ this.computeLayoutInnerRadius(), this.computeLayoutOuterRadius() ] : this._inverse ? [ this._endAngle, this._startAngle ] : [ this._startAngle, this._endAngle ],
(!prevRange || !newRange || prevRange[0] !== newRange[0] || prevRange[1] !== newRange[1]) && (this._scale.range(newRange),
!0);
}
collectSeriesField(depth, series) {
var _a, _b;
let field;
return field = depth > 0 ? null === (_b = null === (_a = series.getGroups()) || void 0 === _a ? void 0 : _a.fields) || void 0 === _b ? void 0 : _b[depth] : "radius" === this.getOrient() ? series.getRadiusField() : series.getAngleField(),
field;
}
updateSeriesScale() {
(0, model_1.eachSeries)(this._regions, (s => {
"radius" === this.getOrient() ? (0, util_1.shouldUpdateAxis)(s.radiusAxisHelper, this.axisHelper(), (0,
vutils_1.isValid)(this._seriesUserId) || (0, vutils_1.isValid)(this._seriesIndex)) && (s.setRadiusScale(this._scale),
s.radiusAxisHelper = this.axisHelper()) : (0, util_1.shouldUpdateAxis)(s.angleAxisHelper, this.axisHelper(), (0,
vutils_1.isValid)(this._seriesUserId) || (0, vutils_1.isValid)(this._seriesIndex)) && (s.setAngleScale(this._scale),
s.angleAxisHelper = this.axisHelper());
}), {
userId: this._seriesUserId,
specIndex: this._seriesIndex
});
}
getSeriesStatisticsField(s) {
const f = "radius" === this.getOrient() ? s.getRadiusField() : s.getAngleField();
return (0, vscale_1.isContinuous)(this._scale.type) ? f : [ f[0] ];
}
initGroupScales() {}
axisHelper() {
return {
isContinuous: (0, vscale_1.isContinuous)(this._scale.type),
dataToPosition: this.dataToPosition.bind(this),
coordToPoint: this.coordToPoint.bind(this),
pointToCoord: this.pointToCoord.bind(this),
center: this.getCenter.bind(this),
layoutRadius: this._computeLayoutRadius.bind(this),
getScale: (depth = 0) => this._scales[depth],
getAxisId: () => this.id,
getSpec: () => this._spec
};
}
positionToData(position) {
const coord = this.pointToCoord(position);
return "radius" === this.getOrient() ? this.invert(coord.radius) : this.invert(coord.angle);
}
coordToPoint(point) {
const center = this.getCenter();
return (0, vutils_1.polarToCartesian)(center, point.radius, point.angle);
}
pointToCoord(point) {
const center = this.getCenter(), startAngle = this._startAngle, endAngle = this._endAngle;
return (0, vutils_1.cartesianToPolar)(point, center, startAngle, endAngle);
}
getOuterRadius() {
return this.computeLayoutOuterRadius();
}
getInnerRadius() {
return this.computeLayoutInnerRadius();
}
updateLayoutAttribute() {
this._visible && ("radius" === this.getOrient() ? this._layoutRadiusAxis() : this._layoutAngleAxis()),
super.updateLayoutAttribute();
}
_getNormalizedValue(values, length) {
return 0 === length ? 0 : (this.dataToPosition(values) - this._getStartValue()) / length;
}
getLabelItems(length) {
var _a;
const tickLatestData = null === (_a = this.getTickData()) || void 0 === _a ? void 0 : _a.getLatestData();
return tickLatestData && tickLatestData.length ? [ tickLatestData.map((obj => (0,
util_1.getAxisItem)(obj.value, this._getNormalizedValue([ obj.value ], length)))) ] : [];
}
_getStartValue() {
return "radius" === this.getOrient() ? this.computeLayoutInnerRadius() : this._startAngle;
}
_layoutAngleAxis() {
var _a, _b, _c;
const center = this.getCenter(), radius = this.computeLayoutOuterRadius(), innerRadius = this.computeLayoutInnerRadius(), angleRange = this._endAngle - this._startAngle, items = this.getLabelItems(angleRange), commonAttrs = Object.assign(Object.assign({}, this.getLayoutStartPoint()), {
inside: this._spec.inside,
center: center,
radius: radius,
innerRadius: innerRadius,
startAngle: this._startAngle,
endAngle: this._endAngle,
sides: (null === (_c = null === (_b = null === (_a = this._getRelatedAxis(this._option.radiusAxisIndex)) || void 0 === _a ? void 0 : _a.getSpec()) || void 0 === _b ? void 0 : _b.grid) || void 0 === _c ? void 0 : _c.smooth) ? void 0 : this.getScale().domain().length
}), attrs = Object.assign(Object.assign({}, commonAttrs), {
size: this.getRefLayoutRect(),
title: {
text: this._spec.title.text || this._dataFieldText
},
items: items,
orient: "angle",
scale: this._scale
});
this._spec.grid.visible && (attrs.grid = Object.assign({
type: "line",
smoothLink: !0,
items: items[0]
}, commonAttrs)), this._update(attrs);
}
_layoutRadiusAxis() {
var _a, _b, _c;
const center = this.getCenter(), radius = this.computeLayoutOuterRadius(), innerRadius = this.computeLayoutInnerRadius(), endPoint = this.coordToPoint({
angle: this._startAngle,
radius: radius
}), startPoint = this.coordToPoint({
angle: this._startAngle,
radius: innerRadius
}), distance = vutils_1.PointService.distancePP(startPoint, endPoint), items = this.getLabelItems(distance), commonAttrs = Object.assign(Object.assign({}, this.getLayoutStartPoint()), {
start: startPoint,
end: endPoint,
verticalFactor: -1
}), attrs = Object.assign(Object.assign({}, commonAttrs), {
title: {
text: this._spec.title.text || this._dataFieldText
},
items: items,
orient: "radius",
scale: this._scale.clone()
});
(null === (_a = this._spec.grid) || void 0 === _a ? void 0 : _a.visible) && (attrs.grid = Object.assign({
items: items[0],
type: (null === (_b = this._spec.grid) || void 0 === _b ? void 0 : _b.smooth) ? "circle" : "polygon",
center: center,
closed: !0,
sides: null === (_c = this._getRelatedAxis(this._option.angleAxisIndex)) || void 0 === _c ? void 0 : _c.getScale().domain().length,
startAngle: this._startAngle,
endAngle: this._endAngle
}, commonAttrs)), this._update(attrs);
}
_getRelatedAxis(index) {
if ((0, vutils_1.isValid)(index)) return this._option.getComponentByIndex(this.specKey, index);
}
_computeLayoutRadius() {
return (0, util_2.computeLayoutRadius)((() => this._spec.layoutRadius), this.getRefLayoutRect, this.getCenter, (() => ({
startAngle: this._startAngle,
endAngle: this._endAngle
})));
}
computeLayoutOuterRadius() {
var _a;
const radius = null !== (_a = this._spec.outerRadius) && void 0 !== _a ? _a : this._spec.radius, outerRadius = null != radius ? radius : this.getRefSeriesRadius().outerRadius;
return this._computeLayoutRadius() * outerRadius;
}
computeLayoutInnerRadius() {
var _a;
const innerRadius = null !== (_a = this._spec.innerRadius) && void 0 !== _a ? _a : this.getRefSeriesRadius().innerRadius;
return this._computeLayoutRadius() * innerRadius;
}
getRefSeriesRadius() {
let outerRadius = polar_1.POLAR_DEFAULT_RADIUS, innerRadius = 0;
const chartSpec = this.getChart().getSpec();
return (0, model_1.eachSeries)(this.getRegions(), (s => {
const series = s;
if ((0, utils_1.isPolarAxisSeries)(series.type)) {
const {outerRadius: seriesRadius = chartSpec.outerRadius, innerRadius: seriesInnerRadius = chartSpec.innerRadius} = series;
(0, vutils_1.isValidNumber)(seriesRadius) && (outerRadius = seriesRadius), (0, vutils_1.isValidNumber)(seriesInnerRadius) && (innerRadius = seriesInnerRadius);
}
}), {
userId: this._seriesUserId,
specIndex: this._seriesIndex
}), {
outerRadius: outerRadius,
innerRadius: innerRadius
};
}
_update(attrs) {
const {grid: gridAttrs} = attrs, axisAttrs = __rest(attrs, [ "grid" ]);
if (this._axisMark.getComponent().setAttributes((0, vutils_extension_1.mergeSpec)({}, this._axisStyle, axisAttrs)),
this._gridMark) {
this._gridMark.getComponent().setAttributes((0, vutils_extension_1.mergeSpec)({}, this._gridStyle, gridAttrs));
}
}
invert(value) {
var _a;
if ("angle" === this.getOrient() && "band" === this._scale.type) {
const range = this._scale.range(), rangeValue = range[range.length - 1] - range[0], offset = .5 === (null !== (_a = this.getSpec().bandPosition) && void 0 !== _a ? _a : this._defaultBandPosition) ? 0 : this._scale.bandwidth() / 2;
if (range[0] < 0) {
const transformedAngle = (value + offset + Math.abs(range[0])) % rangeValue - Math.abs(range[0]);
return this._scale.invert(transformedAngle);
}
return this._scale.invert((value + offset) % rangeValue);
}
return this._scale.invert(value);
}
}
exports.PolarAxis = PolarAxis, PolarAxis.type = type_1.ComponentTypeEnum.polarAxis,
PolarAxis.specKey = "axes";
//# sourceMappingURL=axis.js.map