Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Apply best practices for creating programmatic videos with Remotion and React.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
rules/charts.md
1---2name: charts3description: Chart and data visualization patterns for Remotion. Use when creating bar charts, pie charts, line charts, stock graphs, or any data-driven animations.4metadata:5tags: charts, data, visualization, bar-chart, pie-chart, line-chart, stock-chart, svg-paths, graphs6---78# Charts in Remotion910Create charts using React code - HTML, SVG, and D3.js are all supported.1112Disable all animations from third party libraries - they cause flickering.13Drive all animations from `useCurrentFrame()`.1415## Bar Chart1617```tsx18const STAGGER_DELAY = 5;19const frame = useCurrentFrame();20const { fps } = useVideoConfig();2122const bars = data.map((item, i) => {23const height = spring({24frame,25fps,26delay: i * STAGGER_DELAY,27config: { damping: 200 },28});29return <div style={{ height: height * item.value }} />;30});31```3233## Pie Chart3435Animate segments using stroke-dashoffset, starting from 12 o'clock:3637```tsx38const progress = interpolate(frame, [0, 100], [0, 1]);39const circumference = 2 * Math.PI * radius;40const segmentLength = (value / total) * circumference;41const offset = interpolate(progress, [0, 1], [segmentLength, 0]);4243<circle44r={radius}45cx={center}46cy={center}47fill="none"48stroke={color}49strokeWidth={strokeWidth}50strokeDasharray={`${segmentLength} ${circumference}`}51strokeDashoffset={offset}52transform={`rotate(-90 ${center} ${center})`}53/>;54```5556## Line Chart / Path Animation5758Use `@remotion/paths` for animating SVG paths (line charts, stock graphs, signatures).5960Install: `npx remotion add @remotion/paths`61Docs: https://remotion.dev/docs/paths.md6263### Convert data points to SVG path6465```tsx66type Point = { x: number; y: number };6768const generateLinePath = (points: Point[]): string => {69if (points.length < 2) return "";70return points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");71};72```7374### Draw path with animation7576```tsx77import { evolvePath } from "@remotion/paths";7879const path = "M 100 200 L 200 150 L 300 180 L 400 100";80const progress = interpolate(frame, [0, 2 * fps], [0, 1], {81extrapolateLeft: "clamp",82extrapolateRight: "clamp",83easing: Easing.out(Easing.quad),84});8586const { strokeDasharray, strokeDashoffset } = evolvePath(progress, path);8788<path89d={path}90fill="none"91stroke="#FF3232"92strokeWidth={4}93strokeDasharray={strokeDasharray}94strokeDashoffset={strokeDashoffset}95/>;96```9798### Follow path with marker/arrow99100```tsx101import {102getLength,103getPointAtLength,104getTangentAtLength,105} from "@remotion/paths";106107const pathLength = getLength(path);108const point = getPointAtLength(path, progress * pathLength);109const tangent = getTangentAtLength(path, progress * pathLength);110const angle = Math.atan2(tangent.y, tangent.x);111112<g113style={{114transform: `translate(${point.x}px, ${point.y}px) rotate(${angle}rad)`,115transformOrigin: "0 0",116}}117>118<polygon points="0,0 -20,-10 -20,10" fill="#FF3232" />119</g>;120```121