← 글 목록

notes

chart js

Chart.js 차트 구성·데이터셋·옵션 설정과 React 적용 메모.

  • 범례는 기본이 색 상자고, 점 모양을 쓰려면 usePointStyle: true 를 먼저 켜야 한다.
  • 켜면 크기는 pointStyleWidth, 없으면 boxWidth 와 글자 크기 중 작은 값으로 정해진다.
  • 막대든 라인이든 차트 종류와 상관없이 이 규칙은 같다.

범례 모양이 안 바뀌던 이유

막대 차트 범례를 동그라미로 바꾸려고 이렇게 썼는데 아무 변화가 없었다.

처음 쓴 옵션
options: {
  plugins: {
    legend: {
      position: "bottom",
      labels: {
        pointStyle: "circle",
        pointStyleWidth: 10,
        boxWidth: 10,
      },
    },
    datalabels: {
      color: (context) =>
        context.dataIndex === 0 || context.dataIndex === 5 ? "black" : "white",
    },
  },
},

상자만 작아지고 동그라미는 안 나왔다. 처음에는 막대 차트라서 pointStyle 이 안 먹힌다고 생각했는데, 알고 보니 차트 종류 문제가 아니었다.

범례는 기본으로 항상 색 상자를 그린다. 라인 차트도 마찬가지다. legend.labels.pointStyle 과 pointStyleWidth 는 usePointStyle: true 가 있을 때만 읽힌다.


옵션별 역할

legend.labels.pointStyle 을 안 주면 데이터셋에 설정한 pointStyle 을 따라간다. 라인 차트에서 데이터셋에 pointStyle: 'circle' 을 줘도, 범례는 usePointStyle 이 없으면 여전히 상자다.


점 크기는 어떻게 정해지나

usePointStyle: true 일 때 점 크기는 이 순서로 정해진다.

  • pointStyleWidth 가 있으면 그 값.
  • 없으면 boxWidth 와 글자 크기 중 작은 값. 기본값이면 boxWidth 40, 글자 12 라서 12 가 된다.

그래서 점을 키우고 싶을 때 boxWidth 만 올리면 글자 크기에 막혀서 안 커진다. pointStyleWidth 를 직접 주는 게 편하다.


고친 코드

결국 빠진 건 usePointStyle: true 하나였다.

plugins: {
  legend: {
    position: "bottom",
    labels: {
      usePointStyle: true,
      pointStyle: "circle",
      pointStyleWidth: 10,
    },
  },
},

막대 차트 전체 예시는 이렇다.

막대 차트 + 동그라미 범례
const myChart = new Chart(ctx, {
  type: "bar",
  data: {
    labels: ["January", "February", "March", "April", "May"],
    datasets: [
      {
        label: "Sales",
        data: [10, 20, 30, 40, 50],
        backgroundColor: "rgba(75, 192, 192, 0.2)",
        borderColor: "rgba(75, 192, 192, 1)",
        borderWidth: 1,
      },
    ],
  },
  options: {
    plugins: {
      legend: {
        position: "bottom",
        labels: {
          usePointStyle: true,
          pointStyle: "circle",
          pointStyleWidth: 10,
          font: { size: 14 },
        },
      },
    },
  },
});

라인 차트도 똑같다. 데이터셋의 pointStyle, pointRadius 는 차트 안의 점 모양이고, 범례 모양은 legend.labels 쪽 설정이다.

라인 차트 예시
const myChart = new Chart(ctx, {
  type: "line",
  data: {
    labels: ["January", "February", "March", "April", "May"],
    datasets: [
      {
        label: "Sales",
        data: [10, 20, 30, 40, 50],
        borderColor: "rgba(75, 192, 192, 1)",
        backgroundColor: "rgba(75, 192, 192, 0.2)",
        pointStyle: "circle", // 차트 안의 점
        pointRadius: 5,
      },
    ],
  },
  options: {
    plugins: {
      legend: {
        position: "bottom",
        labels: {
          usePointStyle: true, // 이게 있어야 범례도 점이 된다
          pointStyleWidth: 10,
        },
      },
    },
  },
});

react-chartjs-2 를 쓰면 같은 options 객체를 <Bar options={options} data={data} /> 로 넘기면 된다. Chart.js 3 부터는 트리 쉐이킹 때문에 Legend, BarElement 같은 구성 요소를 ChartJS.register() 로 먼저 등록해야 범례가 보인다.