chart-utils
remotionui/chart-utilsFreeUtility
Chart scaling and SVG path helpers
Install it
npx shadcn@latest add https://remotionui.com/r/chart-utils.jsonSource
1/**2 * Chart maths for the charts & metrics layer.3 *4 * Everything here is pure and frame-independent — components own the timing,5 * this file owns the geometry. Screen coordinates are produced in one place so6 * a line, its area fill, its gridlines and its axis labels can never drift out7 * of alignment with each other.8 */910export type ChartDatum = {11 label: string;12 value: number;13 /** Overrides the series colour for this bar/point. */14 color?: string;15 /** Short change annotation, e.g. `"+18%"`. */16 delta?: string;17};1819export type ChartPoint = {20 x: number;21 y: number;22 /** Axis tick label. Falls back to the x value when omitted. */23 label?: string;24};2526export type ChartDomain = {27 min: number;28 max: number;29 span: number;30};3132/** Inner drawing rectangle, in SVG user units. */33export type PlotArea = {34 left: number;35 top: number;36 right: number;37 bottom: number;38 width: number;39 height: number;40};4142export type PlotInsets = {43 top?: number;44 right?: number;45 bottom?: number;46 left?: number;47};4849/** A point projected into plot coordinates, with its source values kept. */50export type PlottedPoint = {51 x: number;52 y: number;53 value: number;54 label?: string;55};5657const clamp01 = (value: number) => Math.min(1, Math.max(0, value));5859/** Raw min/max of a series. `includeZero` anchors bar charts to a true zero. */60export function getChartDomain(61 values: number[],62 { includeZero = false }: { includeZero?: boolean } = {},63): ChartDomain {64 const finite = values.filter((value) => Number.isFinite(value));6566 if (finite.length === 0) {67 return { min: 0, max: 1, span: 1 };68 }6970 const min = Math.min(...finite, includeZero ? 0 : Infinity);71 const max = Math.max(...finite, includeZero ? 0 : -Infinity);7273 // A flat series still needs a span, otherwise every point lands on one line.74 if (min === max) {75 const padding = Math.abs(max) || 1;76 return { min: min - padding, max: max + padding, span: padding * 2 };77 }7879 return { min, max, span: max - min };80}8182/** Rounds a raw step up to the nearest 1 / 2 / 5 × 10ⁿ so ticks read cleanly. */83function niceStep(rawStep: number): number {84 if (rawStep <= 0) return 1;85 const magnitude = 10 ** Math.floor(Math.log10(rawStep));86 const normalized = rawStep / magnitude;87 const step = normalized <= 1 ? 1 : normalized <= 2 ? 2 : normalized <= 5 ? 5 : 10;88 return step * magnitude;89}9091/**92 * Domain snapped outward to round numbers, with the tick values that land93// … truncated
More from remotionui
All 127 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| ai-composer-utilsai-composer-utils | remotionui | Utilities | Free | no deps | |
| audio-viz-utilsaudio-viz-utils | remotionui | Utilities | Free | no deps | |
| caption-utilscaption-utils | remotionui | Utilities | Free | no deps | |
| code-syntaxcode-syntax | remotionui | Utilities | Free | no deps | |
| layoutlayout | remotionui | Utilities | Free | no deps | |
| map-utilsmap-utils | remotionui | Utilities | Free | no deps | |
| media-utilsmedia-utils | remotionui | Utilities | Free | no deps | |
| motion-primitivemotion-primitive | remotionui | Utilities | Free | no deps |
