@visactor/vchart
Version:
charts lib based @visactor/VGrammar
177 lines (167 loc) • 9.65 kB
JavaScript
import { degreeToRadian, isNil, isValid, isValidNumber, binaryFuzzySearch } from "@visactor/vutils";
import { SEGMENT_FIELD_START, STACK_FIELD_END, STACK_FIELD_START } from "../../../constant/data";
import { POLAR_END_RADIAN, POLAR_START_RADIAN } from "../../../constant/polar";
import { AttributeLevel } from "../../../constant/attribute";
import { valueInScaleRange } from "../../../util/scale";
import { PolarSeries } from "../polar";
import { createArc, createRect } from "@visactor/vrender-core";
import { progressLikeSeriesMark } from "./constant";
export class ProgressLikeSeries extends PolarSeries {
constructor() {
super(...arguments), this._arcGroupMark = null, this._getAngleValueStart = datum => {
const axis = this._getAngleAxis(), {tickMask: tickMask} = this._spec;
if ((null == tickMask ? void 0 : tickMask.forceAlign) && this._isTickMaskVisible(axis)) {
const originValue = datum[this.getStack() ? STACK_FIELD_START : SEGMENT_FIELD_START], subTickData = this._getAngleAxisSubTickData(axis), step = subTickData[1].value - subTickData[0].value, offsetAngle = degreeToRadian(tickMask.offsetAngle);
let pos;
if (isValid(originValue)) {
const index = binaryFuzzySearch(subTickData, (tick => tick.value - originValue)), targetIndex = index >= subTickData.length || originValue > subTickData[index].value - step / 2 ? Math.min(index, subTickData.length - 1) : index > 0 ? index - 1 : void 0;
void 0 !== targetIndex && (pos = this.angleAxisHelper.dataToPosition([ subTickData[targetIndex].value - step / 2 ]));
}
return isNil(pos) && (pos = this.angleAxisHelper.dataToPosition([ subTickData[0].value - step / 2 ])),
pos + offsetAngle;
}
return this._getAngleValueStartWithoutMask(datum);
}, this._getAngleValueEnd = datum => {
const axis = this._getAngleAxis(), {tickMask: tickMask} = this._spec;
if ((null == tickMask ? void 0 : tickMask.forceAlign) && this._isTickMaskVisible(axis)) {
const originValue = datum[this.getStack() ? STACK_FIELD_END : this._angleField[0]], subTickData = this._getAngleAxisSubTickData(axis), step = subTickData[1].value - subTickData[0].value, offsetAngle = degreeToRadian(tickMask.offsetAngle), index = binaryFuzzySearch(subTickData, (tick => tick.value - originValue)), targetIndex = index >= subTickData.length || originValue > subTickData[index].value - step / 2 ? Math.min(index, subTickData.length - 1) : index > 0 ? index - 1 : void 0;
let pos;
return pos = void 0 !== targetIndex ? this.angleAxisHelper.dataToPosition([ subTickData[targetIndex].value + step / 2 ]) : this.angleAxisHelper.dataToPosition([ subTickData[0].value - step / 2 ]),
pos + offsetAngle;
}
return this._getAngleValueEndWithoutMask(datum);
};
}
setAttrFromSpec() {
var _a, _b, _c;
super.setAttrFromSpec();
const chartSpec = null === (_a = this._option.globalInstance.getChart()) || void 0 === _a ? void 0 : _a.getSpec(), startAngle = null !== (_b = this._spec.startAngle) && void 0 !== _b ? _b : null == chartSpec ? void 0 : chartSpec.startAngle;
this._startAngle = isValid(startAngle) ? degreeToRadian(startAngle) : POLAR_START_RADIAN;
const endAngle = null !== (_c = this._spec.endAngle) && void 0 !== _c ? _c : null == chartSpec ? void 0 : chartSpec.endAngle;
this._endAngle = isValid(endAngle) ? degreeToRadian(endAngle) : POLAR_END_RADIAN,
this.setAngleField(this._spec.valueField || this._spec.angleField), this.setRadiusField(this._spec.categoryField || this._spec.radiusField),
this._specAngleField = this._angleField.slice(), this._specRadiusField = this._radiusField.slice();
}
getStackGroupFields() {
return this._radiusField;
}
getStackValueField() {
var _a;
return null === (_a = this._angleField) || void 0 === _a ? void 0 : _a[0];
}
getGroupFields() {
return this._angleField;
}
_convertMarkStyle(style) {
const newStyle = super._convertMarkStyle(style);
if (newStyle.fill) {
const value = style.fill;
"conical" !== (null == value ? void 0 : value.gradient) || isValid(null == value ? void 0 : value.startAngle) || isValid(null == value ? void 0 : value.endAngle) || (newStyle.fill = Object.assign(Object.assign({}, value), {
startAngle: this._startAngle,
endAngle: this._endAngle
}));
}
return newStyle;
}
_getAngleValueStartWithoutMask(datum) {
if (this.getStack()) {
const value = valueInScaleRange(this.angleAxisHelper.dataToPosition([ datum[STACK_FIELD_START] ]), this.angleAxisHelper.getScale(0));
if (isValidNumber(value)) return value;
}
return this._startAngle;
}
_getAngleValueEndWithoutMask(datum) {
if (this.getStack()) {
const value = valueInScaleRange(this.angleAxisHelper.dataToPosition([ datum[STACK_FIELD_END] ]), this.angleAxisHelper.getScale(0));
if (isValidNumber(value)) return value;
}
const angle = this.angleAxisHelper.dataToPosition([ datum[this._angleField[0]] ]);
return this._spec.clamp ? valueInScaleRange(angle, this.angleAxisHelper.getScale(0)) : angle;
}
getDimensionField() {
return this._specRadiusField;
}
getMeasureField() {
return this._specAngleField;
}
initMark() {
this._initArcGroupMark();
}
initMarkStyle() {
this._initArcGroupMarkStyle();
}
_initArcGroupMark() {
return this._arcGroupMark = this._createMark(ProgressLikeSeries.mark.group, {
skipBeforeLayouted: !1
}), this._arcGroupMark;
}
_initArcGroupMarkStyle() {
const groupMark = this._arcGroupMark;
groupMark.created(), this.setMarkStyle(groupMark, {
x: 0,
y: 0
}, "normal", AttributeLevel.Series), this._arcGroupMark.setMarkConfig({
interactive: !1,
zIndex: this.layoutZIndex,
clip: !0,
clipPath: () => {
const axis = this._getAngleAxis(), {x: x, y: y} = this.angleAxisHelper.center(), radius = this._computeLayoutRadius();
if (this._isTickMaskVisible(axis)) {
const {tickMask: tickMask} = this._spec, {angle: angle, offsetAngle: offsetAngle, style: style = {}} = tickMask, subTickData = this._getAngleAxisSubTickData(axis), markStyle = style;
return subTickData.map((({value: value}) => {
const pos = this.angleAxisHelper.dataToPosition([ value ]) + degreeToRadian(offsetAngle), angleUnit = degreeToRadian(angle) / 2;
return createArc(Object.assign(Object.assign({}, markStyle), {
x: x,
y: y,
startAngle: pos - angleUnit,
endAngle: pos + angleUnit,
innerRadius: radius * this._innerRadius,
outerRadius: radius * this._outerRadius,
fill: !0
}));
}));
}
const {width: width, height: height} = this.getLayoutRect();
return [ createRect({
width: width,
height: height,
fill: !0
}) ];
}
});
}
_getAngleAxis() {
if (!this.angleAxisHelper) return;
const angleAxisId = this.angleAxisHelper.getAxisId();
return this._option.getChart().getAllComponents().find((component => component.id === angleAxisId));
}
_getAngleAxisTickData(angleAxis) {
var _a;
return null === (_a = null == angleAxis ? void 0 : angleAxis.getTickData()) || void 0 === _a ? void 0 : _a.getLatestData();
}
_isTickMaskVisible(angleAxis) {
const tickData = this._getAngleAxisTickData(angleAxis), {tickMask: tickMask} = this._spec;
return tickMask && !1 !== tickMask.visible && (null == tickData ? void 0 : tickData.length) > 1;
}
_getAngleAxisSubTickData(angleAxis) {
var _a;
const tickData = this._getAngleAxisTickData(angleAxis), subTickData = [], {subTick: subTick = {}, tick: tick = {}} = null !== (_a = null == angleAxis ? void 0 : angleAxis.getSpec()) && void 0 !== _a ? _a : {}, {tickCount: subTickCount = 4} = subTick, {alignWithLabel: alignWithLabel} = tick;
if ((null == tickData ? void 0 : tickData.length) >= 2) {
const tickSegment = tickData[1].value - tickData[0].value;
for (let i = 0; i < tickData.length - 1; i++) {
const pre = tickData[i], next = tickData[i + 1];
subTickData.push(pre);
for (let j = 0; j < subTickCount; j++) {
const percent = (j + 1) / (subTickCount + 1), value = (1 - percent) * pre.value + percent * (next ? next.value : alignWithLabel ? 1 : pre.value + tickSegment);
subTickData.push({
value: value
});
}
}
return subTickData.push(tickData[tickData.length - 1]), subTickData;
}
return tickData;
}
}
ProgressLikeSeries.mark = progressLikeSeriesMark;
//# sourceMappingURL=progress-like.js.map