--- id: react-charts-library-comparison title: React Charts — Recharts / Visx / D3 / Tremor category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [react, charts, dataviz, vibe-coding] tech_stack: { language: "TS / React", applicable_to: ["Frontend"] } applied_in: [] aliases: [Recharts, Visx, D3, Tremor, Nivo, Chart.js, dataviz] --- # React Charts > **Recharts = 빠른 시작, 한정**. **Visx (Airbnb) = D3 위 React 컴포넌트, 유연**. **D3 직접 = 풀 컨트롤**. **Tremor / shadcn charts = dashboard UI 일관성**. ## 📖 핵심 개념 - High-level: 차트 종류 직접 (Bar, Line). 빠른 시작. - Low-level: scale / axis / shape 조립. 유연. - Headless: 행동만, 스타일 너의 것. ## 💻 코드 패턴 ### Recharts (간단) ```tsx import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts'; ``` → Pros: 5분 setup. Cons: 복잡 customization 어려움, 큰 데이터 느림. ### Tremor (대시보드 UI) ```tsx import { Card, AreaChart, Title, Metric, Flex, BadgeDelta } from '@tremor/react'; Sales +12% $12,345 ``` → Tailwind based. Dashboard 만들기 빠름. ### Visx (Airbnb, low-level + React) ```tsx import { LinePath } from '@visx/shape'; import { scaleLinear } from '@visx/scale'; import { AxisBottom, AxisLeft } from '@visx/axis'; import { GridRows, GridColumns } from '@visx/grid'; const xScale = scaleLinear({ domain: [0, 100], range: [0, width] }); const yScale = scaleLinear({ domain: [0, 100], range: [height, 0] }); xScale(d.x)} y={d => yScale(d.y)} stroke="#3b82f6" strokeWidth={2} /> ``` → Pros: D3 의 power + React 의 declarative. Cons: 학습 곡선. ### D3 직접 (max 컨트롤) ```tsx import * as d3 from 'd3'; import { useEffect, useRef } from 'react'; function Chart({ data }: { data: { x: number; y: number }[] }) { const ref = useRef(null); useEffect(() => { const svg = d3.select(ref.current); const x = d3.scaleLinear().domain(d3.extent(data, d => d.x) as [number, number]).range([0, 400]); const y = d3.scaleLinear().domain([0, d3.max(data, d => d.y)!]).range([200, 0]); const line = d3.line().x(d => x(d.x)).y(d => y(d.y)); svg.append('path') .datum(data) .attr('d', line) .attr('fill', 'none') .attr('stroke', '#3b82f6'); }, [data]); return ; } ``` → React 와 D3 dual responsibility — declarative 깨질 수 있음. ### shadcn charts (Recharts wrapper, Tailwind theme) ```tsx import { ChartContainer, ChartTooltip, ChartTooltipContent, ChartConfig } from '@/components/ui/chart'; import { Bar, BarChart, XAxis } from 'recharts'; const config = { sales: { label: 'Sales', color: 'hsl(var(--chart-1))' }, } satisfies ChartConfig; } /> ``` → Recharts power + shadcn theming + a11y. ### 큰 데이터 — canvas ```tsx // React-vis-style 또는 직접 canvas import { Canvas } from '@react-three/fiber'; // 3D 차트 // 또는 visx/visx-glyph + canvas renderer ``` 10K+ 점 = SVG 느림. Canvas 또는 WebGL. ### Animation ```tsx // Recharts: animation 자동 (animationDuration) // Visx + framer-motion ``` ## 🤔 의사결정 기준 | 상황 | 추천 | |---|---| | 빠른 dashboard | Tremor | | 단순 차트 | Recharts | | Custom + Tailwind 일관성 | shadcn charts | | 복잡 / 유연 | Visx | | 풀 컨트롤 + 큰 데이터 | D3 + canvas | | 3D / WebGL | three.js / r3f | | Native mobile | Victory Native / react-native-skia | ## ❌ 안티패턴 - **Recharts 로 10K 점**: 느림. Canvas. - **D3 + React 같이 DOM 조작**: race. D3 가 SVG 만들고 React 가 render layer. - **차트 안에 큰 ResponsiveContainer 매번 resize**: ResizeObserver throttle. - **Tooltip 매 hover 새 객체**: re-render. memoize. - **색 hard-code**: 다크모드 X. theme 사용. - **Axis 너무 많은 tick**: 가독성 낮음. format / count 제한. - **A11y 무시 — SVG only**: aria-label / 표 alternative. ## 🤖 LLM 활용 힌트 - 시작 = Recharts / Tremor. - 큰 / 유연 = Visx. - shadcn charts 가 Tailwind 사용자에게 sweet spot. ## 🔗 관련 문서 - [[Frontend_Design_Tokens]] - [[React_Animation_Performance]] - [[Frontend_A11y_Testing]]