Featuring Design System

BarChart

카테고리별 수치를 막대로 시각화하는 차트 컨테이너.

개요

BarChart는 recharts의 BarChart를 얇게 래핑한 컨테이너입니다. accessibilityLayer가 기본 활성화되며, data 배열의 fill/stroke 속성이 $ 토큰이면 CSS 변수로 자동 해석됩니다.

  • Bar 시리즈와 함께 사용 — fill, stroke, activeBar, background, label 모두 $ 토큰 지원
  • layouthorizontal (기본) 또는 vertical (가로 막대)
  • stackId — 동일 id를 가진 Bar를 누적 표시
  • recharts API 호환 — 래핑되지 않은 props는 recharts 문서 그대로

언제 사용하나요

  • 카테고리별 수치 비교 — 월별 매출, 제품별 판매량
  • 누적 구성비 표현 — 수입/지출 구조, 상태별 비중
  • 순위 시각화 — 가로 막대로 긴 카테고리 라벨 표시

언제 사용하면 안 되나요

  • 시간에 따른 연속 추이LineChart 또는 AreaChart
  • 비율 표현 (전체에서 차지하는 비중)PieChart
  • 단일 지표 간단 표시Sparkline 또는 Typo로 숫자 직접 표기

접근성

  • BarChartaccessibilityLayer가 기본 활성되어 방향키 내비게이션으로 데이터 포인트를 이동할 수 있습니다.
  • Tooltip이 활성된 경우 스크린리더가 해당 값과 라벨을 읽습니다.
  • 컨테이너에 role="img"aria-label을 수동으로 지정하는 것을 권장합니다.
Key동작
Arrow Left / Arrow Right이전/다음 데이터 포인트로 이동
Arrow Up / Arrow Down복수 시리즈 간 이동

Usage

기본 사용법

() => {
const data = [
  { month: '1월', revenue: 4200 },
  { month: '2월', revenue: 3800 },
  { month: '3월', revenue: 5200 },
  { month: '4월', revenue: 4780 },
  { month: '5월', revenue: 3890 },
  { month: '6월', revenue: 4390 },
];
return (
  <ResponsiveContainer width="100%" height={280}>
    <BarChart data={data}>
      <CartesianGrid />
      <XAxis dataKey="month" />
      <YAxis />
      <Bar dataKey="revenue" fill="$primary-50" />
      <ChartTooltip />
    </BarChart>
  </ResponsiveContainer>
);
}

다중 시리즈

Bar를 여러 개 배치하면 그룹 막대 차트가 됩니다.

() => {
const data = [
  { month: '1월', revenue: 4200, expense: 2400 },
  { month: '2월', revenue: 3800, expense: 1398 },
  { month: '3월', revenue: 5200, expense: 4800 },
  { month: '4월', revenue: 4780, expense: 3908 },
  { month: '5월', revenue: 3890, expense: 4800 },
];
return (
  <ResponsiveContainer width="100%" height={280}>
    <BarChart data={data}>
      <CartesianGrid />
      <XAxis dataKey="month" />
      <YAxis />
      <Bar dataKey="revenue" fill="$primary-50" />
      <Bar dataKey="expense" fill="$gray-50" />
      <ChartTooltip />
      <ChartLegend />
    </BarChart>
  </ResponsiveContainer>
);
}

누적 (Stacked)

stackId를 동일하게 지정하면 누적 표시됩니다.

() => {
const data = [
  { month: '1월', revenue: 4200, expense: 2400 },
  { month: '2월', revenue: 3800, expense: 1398 },
  { month: '3월', revenue: 5200, expense: 4800 },
  { month: '4월', revenue: 4780, expense: 3908 },
];
return (
  <ResponsiveContainer width="100%" height={280}>
    <BarChart data={data}>
      <CartesianGrid />
      <XAxis dataKey="month" />
      <YAxis />
      <Bar dataKey="revenue" fill="$primary-50" stackId="a" />
      <Bar dataKey="expense" fill="$teal-50" stackId="a" />
      <ChartTooltip />
      <ChartLegend />
    </BarChart>
  </ResponsiveContainer>
);
}

가로 막대

layout="vertical", XAxis type="number", YAxis type="category" 조합으로 가로 막대 차트를 구성합니다.

() => {
const data = [
  { month: '1월', revenue: 4200 },
  { month: '2월', revenue: 3800 },
  { month: '3월', revenue: 5200 },
  { month: '4월', revenue: 4780 },
];
return (
  <ResponsiveContainer width="100%" height={240}>
    <BarChart data={data} layout="vertical">
      <CartesianGrid />
      <XAxis type="number" />
      <YAxis type="category" dataKey="month" width={40} />
      <Bar dataKey="revenue" fill="$primary-50" barSize={16} />
      <ChartTooltip />
    </BarChart>
  </ResponsiveContainer>
);
}

기준선과 라벨

ReferenceLine으로 목표값을, LabelList로 막대 위 수치를 표시합니다.

() => {
const data = [
  { month: '1월', revenue: 4200 },
  { month: '2월', revenue: 3800 },
  { month: '3월', revenue: 5200 },
  { month: '4월', revenue: 4780 },
  { month: '5월', revenue: 3890 },
];
return (
  <ResponsiveContainer width="100%" height={300}>
    <BarChart data={data}>
      <CartesianGrid />
      <XAxis dataKey="month" />
      <YAxis />
      <Bar dataKey="revenue" fill="$primary-50" barSize={32}>
        <LabelList dataKey="revenue" position="top" />
      </Bar>
      <ReferenceLine
        y={4000}
        stroke="$support-error-3"
        label={{ value: '목표', position: 'insideTopRight' }}
      />
      <ChartTooltip />
    </BarChart>
  </ResponsiveContainer>
);
}

Slot 토큰 — activeBar / background / label

activeBar, background, label 같은 slot prop은 오브젝트 형태일 때 $ 토큰을 해석합니다. React Element나 함수인 경우 그대로 전달됩니다. label 오브젝트에는 fontSize-200 / font.sans / $text-2 기본 typography가 자동 병합되며, 소비자 명시값이 우선합니다.

() => {
const data = [
  { month: '1월', revenue: 4200 },
  { month: '2월', revenue: 3800 },
  { month: '3월', revenue: 5200 },
  { month: '4월', revenue: 4780 },
];
return (
  <ResponsiveContainer width="100%" height={280}>
    <BarChart data={data}>
      <CartesianGrid />
      <XAxis dataKey="month" />
      <YAxis />
      <Bar
        dataKey="revenue"
        fill="$primary-50"
        activeBar={{ fill: '$primary-30', stroke: '$primary-60', strokeWidth: 2 }}
        background={{ fill: '$gray-10' }}
      />
      <ChartTooltip />
    </BarChart>
  </ResponsiveContainer>
);
}

데이터 항목별 색상

data 배열의 각 항목에 fill 속성을 두면 항목별로 다른 색을 적용할 수 있습니다 (resolveDataTokens가 자동 해석).

() => {
const data = [
  { stage: '유입', count: 1000, fill: '$primary-50' },
  { stage: '관심', count: 720, fill: '$teal-50' },
  { stage: '전환', count: 320, fill: '$support-warning-3' },
  { stage: '이탈', count: 80, fill: '$support-error-3' },
];
return (
  <ResponsiveContainer width="100%" height={260}>
    <BarChart data={data}>
      <CartesianGrid />
      <XAxis dataKey="stage" />
      <YAxis />
      <Bar dataKey="count" />
      <ChartTooltip />
    </BarChart>
  </ResponsiveContainer>
);
}

Tick 타이포그래피

XAxis / YAxistick{ typo, fill } 토큰을 전달해 축 레이블을 조정합니다. 기본값은 $caption-1 / $text-3.

() => {
const data = [
  { month: '1월', revenue: 4200 },
  { month: '2월', revenue: 3800 },
  { month: '3월', revenue: 5200 },
  { month: '4월', revenue: 4780 },
];
return (
  <ResponsiveContainer width="100%" height={280}>
    <BarChart data={data}>
      <CartesianGrid />
      <XAxis dataKey="month" tick={{ typo: '$body-1', fill: '$text-1' }} />
      <YAxis tick={{ typo: '$body-1', fill: '$text-1' }} />
      <Bar dataKey="revenue" fill="$primary-50" />
      <ChartTooltip />
    </BarChart>
  </ResponsiveContainer>
);
}

ChartTooltip 커스텀

contentStyle, formatter 등 recharts ChartTooltip의 모든 prop을 사용할 수 있습니다.

() => {
const data = [
  { month: '1월', revenue: 4200 },
  { month: '2월', revenue: 3800 },
  { month: '3월', revenue: 5200 },
];
return (
  <ResponsiveContainer width="100%" height={260}>
    <BarChart data={data}>
      <CartesianGrid />
      <XAxis dataKey="month" />
      <YAxis />
      <Bar dataKey="revenue" fill="$primary-50" />
      <ChartTooltip
        formatter={(value) => [Number(value).toLocaleString() + '원', undefined]}
      />
    </BarChart>
  </ResponsiveContainer>
);
}

Props

recharts BarChart를 래핑합니다. 여기에 명시되지 않은 props는 recharts BarChart API를 참고하세요.

BarChart

extends recharts BarChart

Prop

Type

Bar

extends recharts Bar

Prop

Type