0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Chart.jsでグラフの色を途中で変える

Last updated at Posted at 2023-08-31

目的

折れ線グラフの色を途中で変えたい場合がありますよね。
Chart.jsでの実現方法をまとめます。

ここでは消費税収額を題材にします。
普通にグラフを作成すると以下のとおりです。消費税率は上昇しているので、税率と税収の関係がわかるように、税率ごとに色分けしたくなりますね。

image.png

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Chart</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
  </head>
  <body>
    <canvas id="myChart"></canvas>
    <script>
        const data = [3.3, 4.6, 5.0, 5.2, 5.6, 5.6, 5.8, 6.1, 9.3, 10.1,
                    10.4, 9.8, 9.8, 9.5, 9.7, 10.0, 10.6, 10.5, 10.3, 10.0,
                    9.8, 10.0, 10.2, 10.4, 10.8, 16.0, 17.4, 17.2,17.5, 17.7, 
                    18.4, 21.0, 21.9, 22.2, 23.4];
        const labels = [];
        for (let i = 0; i < data.length; ++i) {
            labels.push((i+1989).toString());
        }
        let lineCtx = document.getElementById("myChart");
        let lineConfig = {
          type: 'line',
          data: {
            labels: labels,
            datasets: [{
              data: data,
              fill: true,
              backgroundColor: 'rgba(252,128,67,0.4)',
              borderColor: 'rgba(252,128,67,1)',
            }, 
          },
          options:{
            scales: {
                x: {
                    display: true,
                    title: {
                        display: true,
                        text: ''
                    }
                },
                y: {
                    display: true,
                    title: {
                        display: true,
                        text: '消費税収 / 兆円'
                    },
                }
            }
          }
        };
        let lineChart = new Chart(lineCtx, lineConfig);
    </script>
  </body>
</html>

解決策

消費税率は3%から5%(1997年), 8%(2014年), 10%(2019年)と上がっています。

この場合はグラフを4本描画し、該当しない区間はNaNで埋めればOKです。
上のコードのスクリプト部分を次のように変更します。

/*
元データ
const data = [3.3, 4.6, 5.0, 5.2, 5.6, 5.6, 5.8, 6.1, 9.3, 10.1, 
                10.4, 9.8, 9.8, 9.5, 9.7, 10.0, 10.6, 10.5, 10.3, 10.0, 
                9.8, 10.0, 10.2, 10.4, 10.8, 16.0, 17.4, 17.2, 17.5, 17.7, 
                18.4, 21.0, 21.9, 22.2, 23.4];
*/

// 元データを4つに分割
const data1 = [3.3, 4.6, 5.0, 5.2, 5.6, 5.6, 5.8, 6.1, 9.3, NaN, 
            NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 
            NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 
            NaN, NaN, NaN, NaN, NaN]

const data2 = [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 9.3, 10.1,
            10.4, 9.8, 9.8, 9.5, 9.7, 10.0, 10.6, 10.5, 10.3, 10.0, 
            9.8, 10, 10.2, 10.4, 10.8, 16.0, NaN, NaN, NaN, NaN, 
            NaN, NaN, NaN, NaN, NaN]

const data3 = [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 
            NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 
            NaN, NaN, NaN, NaN, NaN, 16.0, 17.4, 17.2, 17.5, 17.7, 
            18.4, NaN, NaN, NaN, NaN]

const data4 = [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 
            NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 
            NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 
            18.4, 21.0, 21.9, 22.2, 23.4]


const labels = [];
for (let i = 0; i < data1.length; ++i) {
    labels.push((i+1989).toString());
}
let lineCtx = document.getElementById("myChart");
let lineConfig = {
  type: 'line',
  data: {
    labels: labels,
    // 4つのグラフを作成
    datasets: [{
      label: '税率3%',
      data: data1,
      fill: true,
      backgroundColor: 'rgba(252,128,67,0.4)',
      borderColor: 'rgba(252,128,67,1)',
    }, {
      label: '税率5%',
      data: data2,
      fill: true,
      backgroundColor: 'rgba(75,192,192,0.4)',
      borderColor: 'rgba(75,192,192,1)',
    }, {
      label: '税率8%',
      data: data3,
      fill: true,
      backgroundColor: 'rgba(233,196,106,0.4)',
      borderColor: 'rgba(233,196,106,1)',
    }, {
      label: '税率10%(軽減税率8%)',
      data: data4,
      fill: true,
      backgroundColor: 'rgba(125,125,125,0.4)',
      borderColor: 'rgba(125,125,125,1)',
    }, 
    ],
  },
  options:{
    scales: {
        x: {
            display: true,
            title: {
                display: true,
                text: ''
            }
        },
        y: {
            display: true,
            title: {
                display: true,
                text: '消費税収 / 兆円'
            },
        }
    }
  }
};
let lineChart = new Chart(lineCtx, lineConfig);

次のようにグラフが作成されます。税率変化のタイミングで税収が伸びていることがよく分かります。

image.png

上のコードでは、わかりやすくするため直接NaNに置き換えた4つのデータを記載しました。
たとえば次のようにして、切り替えるタイミングを指定して上記のデータを作成できます。

const points = [1989, 1997, 2014, 2019, 2023].map(a => a-1989);
const data = [3.3, 4.6, 5.0, 5.2, 5.6, 5.6, 5.8, 6.1, 9.3, 10.1, 10.4, 9.8,
            9.8, 9.5, 9.7, 10.0, 10.6, 10.5, 10.3, 10.0, 9.8, 10.0, 10.2, 10.4,
            10.8, 16.0, 17.4, 17.2,17.5, 17.7, 18.4, 21.0, 21.9, 22.2, 23.4];

function generateOutput(data, points) {
    const output = [];
    for (let i=0; i< points.length-1; i++){
        let dataset = [];
        for (let j=0; j< data.length; j++){
            if((points[i] <= j)&&(points[i+1] >= j)){
                dataset.push(data[j])
            } else {
                dataset.push(NaN)
            }
        }
        output.push(dataset)
    }
    return output
}

まとめ

複数のグラフを違う色で描画して一本に見せることで実現できました。

某配信サービスでのコメント推移を可視化するサイトを作成時に知りました。もしよければご覧ください。

利用したデータ

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?