UNPKG

@tanstack/charts

Version:

A chart grammar for TypeScript and JavaScript. Marks consume your data directly, channels describe visual encodings, and the engine compiles them into a renderer-neutral keyed scene. TanStack's compact scales cover common numeric and categorical mappings.

67 lines (66 loc) 2.46 kB
import { valueKey } from "./scales.js"; const focusGroupX = axisFocus("x", true); const focusGroupY = axisFocus("y", true); const focusNearestX = axisFocus("x", false); const focusNearestY = axisFocus("y", false); function axisFocus(axis, grouped) { const coordinate = (point) => axis === "x" ? point.x : point.y; const value = (point) => axis === "x" ? point.xValue : point.yValue; const secondary = (point) => axis === "x" ? point.y : point.x; return { resolve(points, context) { const { x, y, maxDistance } = context; const target = axis === "x" ? x : y; let nearest; let distance = maxDistance; for (const point of points) { const nextDistance = Math.abs(coordinate(point) - target); if (nextDistance >= distance) continue; nearest = point; distance = nextDistance; } if (!nearest) return []; const candidates = groupPoints(points, nearest, value); const secondaryTarget = axis === "x" ? y : x; const primary = candidates.reduce( (closest, candidate) => Math.abs(secondary(candidate) - secondaryTarget) < Math.abs(secondary(closest) - secondaryTarget) ? candidate : closest, nearest ); return grouped ? [primary, ...candidates.filter((point) => point !== primary)] : [primary]; }, group(points, context) { const { point } = context; return grouped ? groupPoints(points, point, value) : [point]; }, navigation(points) { const sorted = [...points].sort( (left, right) => left.x - right.x || left.y - right.y ); if (!grouped) return sorted; const unique = /* @__PURE__ */ new Map(); for (const point of sorted) { const key = valueKey(value(point)); if (!unique.has(key)) unique.set(key, point); } return [...unique.values()]; } }; } function groupPoints(points, point, value) { const key = valueKey(value(point)); const unique = /* @__PURE__ */ new Map(); unique.set(valueKey(point.group), point); for (const candidate of points) { if (valueKey(value(candidate)) !== key) continue; const group = valueKey(candidate.group); if (!unique.has(group)) unique.set(group, candidate); } const sorted = [...unique.values()].sort((left, right) => left.y - right.y); return [point, ...sorted.filter((candidate) => candidate !== point)]; } export { focusGroupX, focusGroupY, focusNearestX, focusNearestY };