← 포트폴리오

데이터 시각화 레퍼런스 · Chart.js 4

📊 Data Viz15종 라이브 차트

Chart.js 4 기반 인터랙티브 차트 15종 — 라이브 데모 + 복사 가능 코드 + 비즈니스 사용 기준 + Remotion 연계 가이드까지. 이 파일 하나면 발표자료 어떤 차트도 대응 가능.

목차

  1. 기본 라인업 — 수직 바·라인·도넛·면적
  2. 비교·분석 — 그룹 바·수평 바·레이더·누적 바
  3. 고급 패턴 — 혼합형·산점도·버블·폭포
  4. KPI 대시보드 — 게이지·카운트업·스파크라인
  5. 차트 선택 가이드 (상황별 매트릭스)
  6. Remotion 연계 — 정적 Chart.js → 영상 애니메이션

01 · 기본 라인업 — 4종

① 수직 바 차트

언제: 기간별 실적·매출 비교. 카테고리 수 7개 이하일 때 가장 깔끔.

bar · Chart.js
new Chart(canvas, {
  type: 'bar',
  data: {
    labels: ['1Q','2Q','3Q','4Q'],
    datasets: [{ label: '매출(억)',
      data: [42,58,51,73],
      backgroundColor: '#38bdf8',
      borderRadius: 6 }]
  },
  options: { plugins:{legend:{display:false}},
    scales:{y:{beginAtZero:true}} }
});
🎬 Remotion 변환: interpolate(frame,[0,20],[0,data])로 바 높이 애니메이션 — BarRace.tsx 패턴 그대로 적용

② 라인 차트

언제: 시계열 트렌드. 기간이 8개 이상이면 바보다 라인이 훨씬 명확.

line · Chart.js
new Chart(canvas, {
  type: 'line',
  data: {
    labels: months,  // 12개 월
    datasets: [{ label: '방문자',
      data: values,
      borderColor: '#38bdf8',
      tension: 0.4,  // 부드러운 곡선
      fill: false,
      pointRadius: 4 }]
  },
  options: { scales:{y:{beginAtZero:false}} }
});
🎬 Remotion 변환: stroke-dashoffset으로 라인이 왼쪽에서 그려지는 self-draw 효과 — Concept 3 패턴

③ 도넛 차트

언제: 5개 이하 구성비. 가운데 공간에 핵심 숫자 삽입하면 KPI 카드 대용.

doughnut · Chart.js
new Chart(canvas, {
  type: 'doughnut',
  data: {
    labels: ['A','B','C','D'],
    datasets: [{ data: [40,25,20,15],
      backgroundColor: [
        '#38bdf8','#818cf8',
        '#34d399','#fbbf24'],
      borderWidth: 2,
      borderColor: '#111c33' }]
  },
  options: { cutout: '65%' }
});
🎬 Remotion 변환: SVG stroke-dasharray로 세그먼트를 순차적으로 그리는 도넛 애니메이션

④ 면적 차트 (Area)

언제: 라인 트렌드에 양(Volume) 강조가 필요할 때. 스택드 면적은 구성비 변화.

line + fill · Chart.js
datasets: [{ label: 'DAU',
  data: values,
  borderColor: '#818cf8',
  backgroundColor: 'rgba(129,140,248,.18)',
  fill: true,  // ← 면적 채우기
  tension: 0.4
}]
🎬 Remotion 변환: clipPath를 오른쪽으로 이동시키며 면적 등장 — spring() + interpolate 조합

02 · 비교·분석 — 4종

⑤ 그룹 바 차트

언제: "A사 vs B사 × 분기별" 등 2차원 비교. 그룹 수 3개 이하 권장.

grouped bar · Chart.js
datasets: [
  { label:'목표', data:[50,60,55,70],
    backgroundColor:'#334155' },
  { label:'실적', data:[42,58,61,73],
    backgroundColor:'#38bdf8' }
]
// options.scales.x.grouped = true (기본값)
🎬 Remotion 변환: 각 그룹 데이터셋에 transition-delay 스태거 적용 — 목표 바 먼저, 실적 바 이어서

⑥ 수평 바 차트 (랭킹)

언제: 항목 이름이 길거나 순위 비교. "Top 10" 형식에 최적.

bar · indexAxis:'y'
options: {
  indexAxis: 'y',  // ← 수평 전환 핵심
  plugins:{ legend:{display:false} },
  scales:{ x:{beginAtZero:true} }
}
🎬 Remotion 변환: BarRace.tsx 그 자체 — 시간 흐름에 따라 순위가 바뀌는 레이싱 바

⑦ 레이더 차트 (역량 평가)

언제: 동일 기준 5~8개 항목 역량/성과 비교. 팀·개인 평가에 자주 사용.

radar · Chart.js
new Chart(canvas, {
  type: 'radar',
  data: {
    labels: ['기획','디자인','개발',
             '커뮤니케이션','리더십'],
    datasets: [{ label:'A팀',
      data: [80,65,90,70,75],
      fill: true,
      backgroundColor:'rgba(56,189,248,.2)',
      borderColor:'#38bdf8' }]
  }
});
🎬 Remotion 변환: 각 꼭짓점을 0→값으로 interpolate, 다각형 fill opacity fade-in

⑧ 누적 바 차트 (Stacked)

언제: 합계+구성비 동시 표현. 기간별 구성 변화 파악.

stacked bar · Chart.js
options: {
  scales: {
    x: { stacked: true },
    y: { stacked: true,
         beginAtZero: true }
  }
}
// datasets 각각 stack:'total' 필요 없음 — stacked:true로 자동
🎬 Remotion 변환: 레이어별 스태거 — 아랫 세그먼트가 먼저 솟고 그 위에 쌓이는 방식

03 · 고급 패턴 — 4종

⑨ 혼합형 Bar + Line

언제: 실적(바)과 목표선·성장률(라인) 동시 표현. 가장 많이 쓰이는 임원 보고 차트.

mixed (bar + line)
datasets: [
  { type:'bar', label:'매출',
    data:[42,58,51,73,68,82],
    backgroundColor:'#1e3a5f',
    borderColor:'#38bdf8',
    borderWidth:1 },
  { type:'line', label:'목표',
    data:[50,50,55,65,70,75],
    borderColor:'#fbbf24',
    borderDash:[6,3],
    pointRadius:0 }
]
🎬 Remotion 변환: 바는 아래서 솟고, 점선 목표선은 stroke-dashoffset으로 왼쪽부터 그려짐

⑩ 산점도 (Scatter)

언제: 두 변수 간 상관관계 파악. "광고비 ↔ 전환율" 등 인과관계 시각화.

scatter · Chart.js
new Chart(canvas, {
  type: 'scatter',
  data: {
    datasets: [{ label:'제품군',
      data: [
        { x:10, y:20 },
        { x:15, y:34 }
        // ...더 많은 포인트
      ],
      pointRadius: 6,
      backgroundColor:'rgba(56,189,248,.7)'
    }]
  }
});
🎬 Remotion 변환: 포인트마다 scale 0→1 스태거 등장 — stagger × spring() 조합

⑪ 버블 차트

언제: x·y·크기 3변수. "시장규모(크기)×성장률(y)×점유율(x)" 포트폴리오 분석.

bubble · Chart.js
new Chart(canvas, {
  type: 'bubble',
  data: {
    datasets: [{ data: [
      { x:20, y:30, r:15 },
      { x:40, y:10, r:25 },
      { x:60, y:50, r:10 }
    ], backgroundColor:'rgba(129,140,248,.5)'
    }]
  }
});
🎬 Remotion 변환: 각 버블 r=0→최종값 으로 scale-up, 라벨 fade-in 스태거

⑫ 폭포 차트 (Waterfall)

언제: 시작값→증감 항목별→최종값 분석. P&L 설명, 비용 구조 분해.

waterfall (stacked trick)
// 투명 오프셋 바 + 실제 값 바 stacked
datasets: [
  { label:'offset',
    data: offsets,  // 투명 바 (기준점)
    backgroundColor:'transparent',
    stack:'w' },
  { label:'증가',
    data: positives,
    backgroundColor:'#34d399',
    stack:'w' },
  { label:'감소',
    data: negatives,
    backgroundColor:'#f87171',
    stack:'w' }
]
🎬 Remotion 변환: 항목별 순차 등장 — 이전 바가 정착한 뒤 다음 바가 솟는 타임라인

04 · KPI 대시보드 — 3종

핵심 지표를 한 눈에 — 숫자가 스크롤 시 0에서 카운트업으로 올라옵니다.

0
월 매출 (억원)
▲ 18.3%
0
신규 고객
▲ 24.1%
0%
고객 유지율
▼ 2.1%p
KPI 카운트업 · Vanilla JS
function countUp(el, target, dur=1800, suffix='') {
  const start = performance.now();
  const tick = t => {
    const p = Math.min(1, (t-start)/dur);
    const ease = 1 - Math.pow(1-p, 3); // easeOut cubic
    el.textContent = Math.round(target * ease) + suffix;
    if (p < 1) requestAnimationFrame(tick);
  };
  requestAnimationFrame(tick);
}
// 사용: countUp(document.getElementById('kpi'), 847, 2000, '억')

게이지 차트 (달성률)

연간 매출 달성률

76%

고객 만족도 (NPS)

82%

프로젝트 완료율

61%
게이지 · doughnut 반원 트릭
new Chart(canvas, {
  type: 'doughnut',
  data: {
    datasets: [{ data: [76, 24],  // 값, 나머지
      backgroundColor: ['#38bdf8', '#1e293b'],
      borderWidth: 0, cutout: '75%' }]
  },
  options: {
    rotation: -90,   // 반원 시작점
    circumference: 180,  // 반원
    plugins: { legend: { display: false } }
  }
});

스파크라인 (인라인 미니 차트)

언제: 표·리스트에 트렌드를 함께 보여줄 때. 별도 축 없이 방향성만 전달.

스파크라인 · 미니 Chart.js
new Chart(sparkCanvas, {
  type: 'line',
  data: { labels: data.map((_,i)=>i),
    datasets: [{ data: sparkData,
      borderColor: color,
      borderWidth: 2,
      fill: false,
      pointRadius: 0,
      tension: 0.4 }] },
  options: {
    animation: false,
    responsive: false,
    scales: { x:{display:false}, y:{display:false} },
    plugins: { legend:{display:false} }
  }
});

05 · 차트 선택 가이드 — 상황별 매트릭스

상황데이터 특성추천 차트피해야 할 것
기간 비교8개 이하 기간수직 바파이 (변화량 안 보임)
기간 비교12개 이상 기간라인 or 면적바 (너무 빽빽함)
구성비5개 이하 항목도넛 or 파이3D 파이 (왜곡)
구성비6개 이상 항목수평 바 (정렬)파이 (색 구분 불가)
순위 비교항목명이 긴 경우수평 바수직 바 (라벨 겹침)
2차원 비교그룹 × 기간그룹 바누적 바 (합계 오해)
구성+합계시간 흐름 포함누적 바그룹 바 (합계 안 보임)
상관관계2변수 포인트산점도라인 (순서 오해)
3변수 분석포트폴리오버블3D 바 (읽기 어려움)
증감 분석P&L·비용 분해폭포단순 라인 (출발점 손실)
역량 평가동일 기준 5~8항목레이더바 (비교 구조 약함)
실적+목표임원 보고혼합형 (바+점선)이중 바 (목표 묻힘)
달성률단일 KPI게이지 or 도넛파이 (기준 불명확)
황금 법칙: 차트 하나에 메시지 하나. 제목을 "월별 매출 추이"가 아닌 "3Q부터 매출 반등"처럼 인사이트로 쓰면 발표 임팩트가 3배 올라간다.

06 · Remotion 연계 — Chart.js → 영상 애니메이션

정적 → 동적 변환 패턴

Chart.js는 웹 발표, Remotion은 mp4 영상. 두 세계의 데이터 구조는 동일 — JSON만 공유하면 됨.

공유 데이터 · data.ts
// 이 데이터를 Chart.js와 Remotion이 공유
export const salesData = [
  { label: '1Q', value: 42 },
  { label: '2Q', value: 58 },
  { label: '3Q', value: 51 },
  { label: '4Q', value: 73 },
];
Chart.js → data.map(d=>d.value) / Remotion → interpolate(frame,...) 동일 데이터 소비

Remotion 바 애니메이션

Chart.js 바 차트를 그대로 Remotion SVG로 변환하는 핵심 패턴.

BarChart.tsx · Remotion
import { useCurrentFrame, interpolate } from 'remotion';

export const BarChart = ({ data }) => {
  const frame = useCurrentFrame();
  return (
    <svg viewBox="0 0 800 400">
      {data.map((d, i) => {
        const h = interpolate(
          frame,
          [i*5, i*5+30],  // 스태거
          [0, d.value * 3],
          { extrapolateRight:'clamp' }
        );
        return <rect key={i}
          x={i*180+20} y={400-h}
          width={120} height={h}
          fill="#38bdf8" rx={6} />;
      })}
    </svg>
  );
};
워크플로: ① Figma/Excel에서 데이터 정리 → ② Chart.js로 웹 슬라이드 빠르게 확인 → ③ 임원 승인 → ④ Remotion으로 동일 데이터 영상화 → ⑤ mp4 삽입. 데이터를 두 번 입력하지 않아도 된다.