@visactor/vchart
Version:
charts lib based @visactor/VGrammar
60 lines (53 loc) • 3.62 kB
JavaScript
import { couldBeValidNumber } from "../../util/type";
import { getPercentValue } from "../../util/math";
import { ARC_TRANSFORM_VALUE } from "../../constant/polar";
import { computeQuadrant, isNil } from "@visactor/vutils";
function transformInvalidValue(value) {
return couldBeValidNumber(value) ? Number.parseFloat(value) : 0;
}
export const pie = (originData, op) => {
const {asStartAngle: asStartAngle, asEndAngle: asEndAngle, asMiddleAngle: asMiddleAngle, asRadian: asRadian, asRatio: asRatio, asQuadrant: asQuadrant, asK: asK, showAllZero: showAllZero, supportNegative: supportNegative, showEmptyCircle: showEmptyCircle} = op, angleField = op.angleField(), startAngle = op.startAngle(), endAngle = op.endAngle(), minAngle = op.minAngle(), data = originData.map((datum => Object.assign({}, datum)));
if (!data || 0 === data.length) return data;
if (!showAllZero && showEmptyCircle && isDataEmpty(data, angleField, supportNegative)) return [];
const appendArcInfo = (data, startAngle, angle) => {
data[asStartAngle] = startAngle, data[asEndAngle] = startAngle + angle, data[asMiddleAngle] = startAngle + angle / 2,
data[asRadian] = angle, data[asQuadrant] = computeQuadrant(startAngle + angle / 2);
};
let total = 0, max = -1 / 0, isAllZero = !0;
for (let index = 0; index < data.length; index++) {
const angleFieldValue = supportNegative ? Math.abs(transformInvalidValue(data[index][angleField])) : transformInvalidValue(data[index][angleField]);
total += angleFieldValue, max = Math.max(angleFieldValue, max), isAllZero && 0 !== angleFieldValue && (isAllZero = !1),
data[index][ARC_TRANSFORM_VALUE] = angleFieldValue;
}
const valueList = data.map((d => Number(d[angleField]))), angleRange = endAngle - startAngle;
let lastAngle = startAngle, restAngle = angleRange, largeThanMinAngleTotal = 0;
const percents = getPercentValue(valueList);
if (data.forEach(((d, i) => {
const angleFieldValue = d[ARC_TRANSFORM_VALUE], ratio = total ? angleFieldValue / total : 0;
let radian = ratio * angleRange;
radian < minAngle ? (radian = minAngle, restAngle -= minAngle) : largeThanMinAngleTotal += angleFieldValue;
const dStartAngle = lastAngle, dEndAngle = lastAngle + radian;
d[asRatio] = ratio, d[asK] = max ? angleFieldValue / max : 0, d._percent_ = percents[i],
appendArcInfo(d, dStartAngle, radian), lastAngle = dEndAngle;
})), restAngle < angleRange) if (restAngle <= .001) {
const angle = angleRange / data.length;
data.forEach(((d, index) => {
appendArcInfo(d, startAngle + index * angle, angle);
}));
} else {
const unitRadian = restAngle / largeThanMinAngleTotal;
lastAngle = startAngle, data.forEach((d => {
const angle = d[asRadian] === minAngle ? minAngle : d[ARC_TRANSFORM_VALUE] * unitRadian;
appendArcInfo(d, lastAngle, angle), lastAngle += angle;
}));
}
if (0 !== total && (data[data.length - 1][asEndAngle] = endAngle), isAllZero && showAllZero) {
const angle = angleRange / data.length;
data.forEach(((d, index) => {
appendArcInfo(d, startAngle + index * angle, angle);
}));
}
return data;
};
export const isDataEmpty = (data, angleField, supportNegative) => !!isNil(data) || (0 === data.length || (!!data.every((datum => 0 === transformInvalidValue(datum[angleField]))) || !supportNegative && 0 === data.reduce(((sum, datum) => sum + transformInvalidValue(datum[angleField])), 0)));
//# sourceMappingURL=pie.js.map