🍩

Chart.jsを使ってドーナツチャートの中央に文字列を表示する

2023/07/18に公開

Chart.jsを使ってドーナツチャートの中央に文字列を表示させようとした時に、少し手間取ったので忘れないようにメモしておきたいと思います。

はじめに

Chart.jsおよびvue-chartjs(Chart.jsをvueで使うためのラッパー)を使って画像のようにドーナツチャートの中央に文字列を表示させることをゴールとします。
また、Nuxt3の環境がすでに構築されている前提で進めていきます。

環境

nuxt 3.6.2
chart.js 4.3.0
vue-chartjs 5.2.0

chart.jsとvue-chartjsのインストール

まずはchart.jsとvue-chartjsをインストールします。

$ npm install vue-chartjs chart.js

ドーナツチャートの描画

次にドーナツチャートを描画してみます。

<script setup>~</script>内で、 data 変数でデータや色の指定を定義し、options 変数、チャートのタイトルや凡例の表示の指定を定義します。

<template>~</template>内で <Doughnut>タグを使い、data,options プロップス でscript内で定義した変数をそれぞれ指定します。

doughnutChart.vue
<script setup lang="ts">
import { Chart as ChartJS, ArcElement, Tooltip, Title, Legend } from 'chart.js'
import { Doughnut } from 'vue-chartjs'
ChartJS.register(ArcElement, Tooltip, Title, Legend)

// チャート用のデータ
const data = {
  labels: [
    'Red',
    'Blue',
    'Yellow'
  ],
  datasets: [{
    data: [80, 15, 5],
    backgroundColor: [
      'rgb(255, 99, 132)',
      'rgb(54, 162, 235)',
      'rgb(255, 205, 86)'
    ],
  }]
};

// チャート描画のオプション
const options = {
  responsive: true,
  maintainAspectRatio: false,
  plugins: {
    title: {
      display: true,
      text: 'Doughnut Chart',
      font: {
        weight: 'bold',
        size: 40},
    },
    legend: {
      display: true,
      position: 'bottom',
      reverse: true,
      labels: {
        font: {
          size: 20
        }
      }
    },
  }
}

</script>
<template>
  <div>
    <div class="doughnut-graph">
    <!-- ドーナツチャートの描画 -->
      <Doughnut
	:data="data"
	:options="options"
      />
     </div>
  </div>
</template>
<style >
.doughnut-graph {
  width: 600px;
  height: 600px;
}
</style>

うまく描画できました。

ドーナツチャートの中央に文字列を追加

ではドーナツチャートの中央に文字列を追加してみましょう。

Chart.jsはcanvas(ブラウザに図を描くために策定された仕様)が使われており、グラフに任意の文字列を追加するには、プラグインを使ってデフォルトで描画される部分を変更する必要があります。

<script setup>~</script>内に ratioText というオブジェクトを定義します。
今回の場合、ratioText 内のbeforeDraw関数 がcanvasを操作する箇所になります。

<script setup lang="ts">
...

const options = {
...
}

// ドーナツチャートの中央に表示させるプラグインを定義する
const ratioText = {
  id: 'ratio-text',
  beforeDraw (chart: any) {
    const { ctx, chartArea: { top, width, height } } = chart
    ctx.save()
    //チャート描画部分の中央を指定
    ctx.fillRect(width / 2, top + (height / 2), 0, 0)
    //フォントのスタイル指定
    ctx.font = 'bold 50px Roboto'
    ctx.fillStyle = '#333333'
    ctx.textAlign = 'center'
    ctx.textBaseline = 'middle'
    //80%という文字列をドーナツチャートの中央部に描画します
    ctx.fillText('80 %', width / 2, top + (height / 2))
  }
}
</script>

<template>~</template>内の <Doughnut>タグに pluginsプロップスを追加し、"[ratioText]"を指定します。

最初はChart.jsの公式ページにあるように optionsplugins プロパティで指定していたのですが、思ったように描画されませんでした。
そこでvue-chartjsを見ると[pluginsプロップス] (https://vue-chartjs.org/api/#props)があったので、こちらを使うことで描画させることができました。

<template>
  <div>
    <div class="doughnut-graph">
      <Doughnut
	:data="data"
	:options="options"
	:plugins="[ratioText]"
      />
    </div>
  </div>
</template>

ドーナツチャートの中央に文字列を表示することができました。

レスキューナウテックブログ

Discussion