UNPKG

@visactor/vrender-components

Version:

components library for dp visualization

72 lines (64 loc) 4.3 kB
import { isFunction, isValid, maxInArray, minInArray, isNumberClose } from "@visactor/vutils"; import { MIN_TICK_GAP, convertDomainToTickData, labelOverlap } from "../util"; import { AABBBounds } from "@visactor/vutils"; import { initTextMeasure } from "../../../util/text"; import { getPolarAngleLabelPosition } from "../../util"; export const getPolarAngleLabelBounds = (scale, domain, op) => { var _a; const {labelStyle: labelStyle, getRadius: getRadius, labelOffset: labelOffset, labelFormatter: labelFormatter, inside: inside} = op, radius = null == getRadius ? void 0 : getRadius(), labelAngle = null !== (_a = labelStyle.angle) && void 0 !== _a ? _a : 0, textMeasure = initTextMeasure(labelStyle); return domain.map((v => { const str = labelFormatter ? labelFormatter(v) : `${v}`, {width: width, height: height} = textMeasure.quickMeasure(str), textWidth = Math.max(width, MIN_TICK_GAP), textHeight = Math.max(height, MIN_TICK_GAP), angle = scale.scale(v), center = { x: 0, y: 0 }; let textX = 0, textY = 0; const orient = { align: labelStyle.textAlign, baseline: labelStyle.textBaseline }, {x: x, y: y} = getPolarAngleLabelPosition(angle, center, radius, labelOffset, inside); orient.align || (isNumberClose(x, center.x) ? orient.baseline || (orient.baseline = y > center.y ? "top" : "bottom") : x > center.x ? orient.align = "left" : x < center.x && (orient.align = "right")), textX = x + ("right" === orient.align ? -textWidth : "left" === orient.align ? 0 : -textWidth / 2), textY = y + ("bottom" === orient.baseline ? -textHeight : "top" === orient.baseline ? 0 : -textHeight / 2); return (new AABBBounds).set(textX, textY, textX + textWidth, textY + textHeight).rotate(labelAngle, textX + textWidth / 2, textY + textHeight / 2); })); }; export const polarAngleAxisDiscreteTicks = (scale, op) => { const {tickCount: tickCount, forceTickCount: forceTickCount, tickStep: tickStep, getRadius: getRadius, labelOffset: labelOffset, labelGap: labelGap = 0, labelStyle: labelStyle} = op, radius = null == getRadius ? void 0 : getRadius(); if (!radius) return convertDomainToTickData(scale.domain()); let scaleTicks; if (isValid(tickStep)) scaleTicks = scale.stepTicks(tickStep); else if (isValid(forceTickCount)) scaleTicks = scale.forceTicks(forceTickCount); else if (isValid(tickCount)) { const range = scale.range(), rangeSize = Math.abs(range[range.length - 1] - range[0]), count = isFunction(tickCount) ? tickCount({ axisLength: rangeSize, labelStyle: labelStyle }) : tickCount; scaleTicks = scale.ticks(count); } else if (op.sampling) { const domain = scale.domain(), range = scale.range(), labelBoundsList = getPolarAngleLabelBounds(scale, domain, op), rangeStart = minInArray(range), rangeEnd = maxInArray(range), incrementUnit = Math.abs(rangeEnd - rangeStart) * (radius + labelOffset) / domain.length, {step: step, delCount: delCount} = getStep(domain, labelBoundsList, labelGap, Math.floor(labelBoundsList.reduce(((min, curBounds) => Math.min(min, curBounds.width(), curBounds.height())), Number.MAX_VALUE) / incrementUnit)); scaleTicks = scale.stepTicks(step), scaleTicks = scaleTicks.slice(0, scaleTicks.length - delCount); } else scaleTicks = scale.domain(); return convertDomainToTickData(scaleTicks); }; const getStep = (domain, labelBoundsList, labelGap, defaultStep) => { let step = defaultStep; do { let success = !0; step++; let ptr = 0; do { ptr + step < domain.length && labelOverlap(labelBoundsList[ptr], labelBoundsList[ptr + step], labelGap) && (success = !1), ptr += step; } while (success && ptr < domain.length); if (success) break; } while (step <= domain.length); let delCount = 0; if (domain.length > 2) { let ptr = domain.length - domain.length % step; for (ptr >= domain.length && (ptr -= step); ptr > 0 && labelOverlap(labelBoundsList[0], labelBoundsList[ptr]); ) delCount++, ptr -= step; } return { step: step, delCount: delCount }; }; //# sourceMappingURL=polar-angle.js.map