UNPKG

@visactor/vchart

Version:

charts lib based @visactor/VGrammar

60 lines (53 loc) 3.62 kB
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