Featuring Design System

PieChart

전체에서 차지하는 비율을 원형으로 시각화하는 차트 컨테이너.

개요

PieChart는 recharts의 PieChart를 얇게 래핑한 컨테이너입니다. Pie 시리즈에 data를 직접 전달하며, 각 항목의 색상은 data[i].fill 또는 Cell 컴포넌트로 지정합니다.

  • Pie 시리즈data, activeShape, inactiveShape, label까지 $ 토큰 해석
  • Cell — recharts re-export. 각 섹터별 색상 지정
  • innerRadius — 설정 시 도넛 차트로 전환

언제 사용하나요

  • 전체 대비 비율 — 플랫폼별 점유율, 응답 분포
  • 5개 이하의 명확히 구분되는 카테고리 — 그 이상은 가독성 저하
  • 도넛 차트로 중앙에 수치 표시가 필요할 때

언제 사용하면 안 되나요

  • 정확한 값 비교BarChart (시각적 면적 비교가 어려움)
  • 시간 추이AreaChart 또는 LineChart
  • 카테고리가 많은 경우 (6개 이상)BarChart (순위 명확)

접근성

  • accessibilityLayer 기본 활성.
  • Pie 섹터는 색상만으로 구분되므로 label 또는 ChartLegend로 이름과 값을 함께 표기할 것을 권장합니다.

Usage

기본 사용법

Pie.data에 배열을 전달하고, 각 항목의 fill로 섹터 색상을 지정합니다.

() => {
const data = [
  { name: '인스타그램', value: 420, fill: '$primary-50' },
  { name: '유튜브', value: 310, fill: '$teal-50' },
  { name: '틱톡', value: 230, fill: '$lightBlue-40' },
  { name: '블로그', value: 140, fill: '$gray-50' },
];
return (
  <ResponsiveContainer width="100%" height={300}>
    <PieChart>
      <Pie data={data} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={100} />
      <ChartTooltip />
      <ChartLegend />
    </PieChart>
  </ResponsiveContainer>
);
}

도넛 (Donut)

innerRadius를 설정하면 도넛 차트가 됩니다.

() => {
const data = [
  { name: '인스타그램', value: 420, fill: '$primary-50' },
  { name: '유튜브', value: 310, fill: '$teal-50' },
  { name: '틱톡', value: 230, fill: '$lightBlue-40' },
  { name: '블로그', value: 140, fill: '$gray-50' },
];
return (
  <ResponsiveContainer width="100%" height={300}>
    <PieChart>
      <Pie data={data} dataKey="value" nameKey="name" cx="50%" cy="50%" innerRadius={60} outerRadius={100} />
      <ChartTooltip />
      <ChartLegend />
    </PieChart>
  </ResponsiveContainer>
);
}

Cell로 섹터별 색상 지정

Cell을 사용하면 data 배열에 fill을 넣지 않고도 섹터별 색상을 지정할 수 있습니다. Cell은 recharts re-export이므로 resolveToken으로 $토큰을 직접 해석합니다.

() => {
const data = [
  { name: '인스타그램', value: 420 },
  { name: '유튜브', value: 310 },
  { name: '틱톡', value: 230 },
  { name: '블로그', value: 140 },
];
const fills = ['$primary-50', '$teal-50', '$lightBlue-40', '$gray-50'];
return (
  <ResponsiveContainer width="100%" height={300}>
    <PieChart>
      <Pie data={data} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={100}>
        {data.map((_, i) => (
          <Cell key={i} fill={resolveToken(fills[i])} />
        ))}
      </Pie>
      <ChartTooltip />
      <ChartLegend />
    </PieChart>
  </ResponsiveContainer>
);
}

Label 표시

label={true}로 기본 라벨을, 함수로 커스텀 라벨을 지정합니다.

() => {
const data = [
  { name: '인스타그램', value: 420, fill: '$primary-50' },
  { name: '유튜브', value: 310, fill: '$teal-50' },
  { name: '틱톡', value: 230, fill: '$lightBlue-40' },
  { name: '블로그', value: 140, fill: '$gray-50' },
];
return (
  <ResponsiveContainer width="100%" height={300}>
    <PieChart>
      <Pie
        data={data}
        dataKey="value"
        nameKey="name"
        cx="50%"
        cy="50%"
        outerRadius={90}
        label={({ name, percent }) => name + ' ' + ((percent ?? 0) * 100).toFixed(0) + '%'}
      />
      <ChartTooltip />
    </PieChart>
  </ResponsiveContainer>
);
}

반원 (Half Pie)

startAngle/endAngle로 파이의 렌더 각도를 제어합니다. cy="100%"를 함께 쓰면 차트 하단에서 시작하는 반원 게이지가 됩니다.

() => {
const data = [
  { name: '인스타그램', value: 420, fill: '$primary-50' },
  { name: '유튜브', value: 310, fill: '$teal-50' },
  { name: '틱톡', value: 230, fill: '$lightBlue-40' },
  { name: '블로그', value: 140, fill: '$gray-50' },
];
return (
  <ResponsiveContainer width="100%" height={220}>
    <PieChart>
      <Pie
        data={data}
        dataKey="value"
        nameKey="name"
        cx="50%"
        cy="100%"
        startAngle={180}
        endAngle={0}
        innerRadius={60}
        outerRadius={110}
      />
      <ChartTooltip />
      <ChartLegend />
    </PieChart>
  </ResponsiveContainer>
);
}

activeShape

호버된 섹터 스타일. 오브젝트일 때 fill/stroke $토큰 해석.

() => {
const data = [
  { name: '인스타그램', value: 420, fill: '$primary-50' },
  { name: '유튜브', value: 310, fill: '$teal-50' },
  { name: '틱톡', value: 230, fill: '$lightBlue-40' },
  { name: '블로그', value: 140, fill: '$gray-50' },
];
return (
  <ResponsiveContainer width="100%" height={280}>
    <PieChart>
      <Pie
        data={data}
        dataKey="value"
        nameKey="name"
        cx="50%"
        cy="50%"
        outerRadius={100}
        activeShape={{ fill: '$primary-30', stroke: '$primary-60', strokeWidth: 2 }}
      />
      <ChartTooltip />
    </PieChart>
  </ResponsiveContainer>
);
}

inactiveShape

호버되지 않은 섹터의 스타일.

() => {
const data = [
  { name: '인스타그램', value: 420, fill: '$primary-50' },
  { name: '유튜브', value: 310, fill: '$teal-50' },
  { name: '틱톡', value: 230, fill: '$lightBlue-40' },
  { name: '블로그', value: 140, fill: '$gray-50' },
];
return (
  <ResponsiveContainer width="100%" height={280}>
    <PieChart>
      <Pie
        data={data}
        dataKey="value"
        nameKey="name"
        cx="50%"
        cy="50%"
        outerRadius={100}
        inactiveShape={{ fill: '$gray-20' }}
      />
      <ChartTooltip />
    </PieChart>
  </ResponsiveContainer>
);
}

label 오브젝트 형태

라벨 텍스트 스타일을 오브젝트로 지정하면 fill $토큰이 해석됩니다. label 오브젝트에는 fontSize-200 / font.sans / $text-2 기본 typography가 자동 병합되며, 소비자 명시값이 우선합니다. (함수형 label은 그대로 전달됩니다.)

() => {
const data = [
  { name: '인스타그램', value: 420, fill: '$primary-50' },
  { name: '유튜브', value: 310, fill: '$teal-50' },
  { name: '틱톡', value: 230, fill: '$lightBlue-40' },
  { name: '블로그', value: 140, fill: '$gray-50' },
];
return (
  <ResponsiveContainer width="100%" height={280}>
    <PieChart>
      <Pie
        data={data}
        dataKey="value"
        nameKey="name"
        cx="50%"
        cy="50%"
        outerRadius={100}
        label={{ fill: '$text-1' }}
      />
      <ChartTooltip />
    </PieChart>
  </ResponsiveContainer>
);
}

Props

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

PieChart

extends recharts PieChart

Prop

Type

Pie

extends recharts Pie

Prop

Type

Cell

recharts re-export. 래핑되지 않았으므로 $토큰 사용 시 resolveToken으로 직접 해석해야 합니다.

Prop

Type