chart.js 在X軸每個區間的長條圖上畫折線圖

經手的幾個專案,echarts 套件改成 Chart.js 的工作在終於告一段落,今天解決的最後一個問題是,在 X 軸的每個區間有三個長條圖,同時在長條圖上要要一個點來跑線圖,結果如下圖。簡單筆記一下作法,順便複習一下今天做的過程。

比較難用語言描述要畫的圖,直接看最後結果吧。

因為 Chart.js 原始設定, 折線圖在每一個 X 軸區間只能畫一個點,而且是畫在每個區間的正中央,如果要在每一隻長條圖上畫點,需要另外寫 plugin。

設置 <canvas>

<div class="chartCard">
      <div class="chartBox">
        <canvas id="myChart"></canvas>
      </div>
</div>

資料設定

const data = {
        labels: ["2022-10-20", "2022-10-21"],
        datasets: [
          {
            label: "Red Sales",
            type: "bar",
            order: 1,
            data: [18, 12, 6, 9, 12, 3, 9],
            backgroundColor: ["rgba(255, 26, 104, 0.2)"],
            borderColor: ["rgba(255, 26, 104, 1)"],
            borderWidth: 1,
          },
          {
            label: "Blue Sales",
            type: "bar",
            order: 1,
            data: [12, 9, 6, 9, 12, 3, 9],
            backgroundColor: ["rgba(54, 162, 235, 0.2)"],
            borderColor: ["rgba(54, 162, 235, 1)"],
            borderWidth: 1,
          },
          {
            label: "Yellow Sales",
            type: "bar",
            order: 1,
            data: [6, 6, 6, 9, 12, 3, 9],
            backgroundColor: ["rgba(255, 206, 86, 0.2)"],
            borderColor: ["rgba(255, 206, 86, 1)"],
            borderWidth: 1,
          },
          {
            label: "Black Sales",
            type: "line",
            order: 0,
            data: [
              { x: "2022-10-20", y: 1 },
              { x: "2022-10-20", y: 2 },
              { x: "2022-10-20", y: 3 },
              { x: "2022-10-21", y: 6 },
              { x: "2022-10-21", y: 9 },
              { x: "2022-10-21", y: 12 },
            ],
            backgroundColor: ["rgba(0, 0, 0, 0.2)"],
            borderColor: ["rgba(0, 0, 0, 1)"],
            borderWidth: 1,
          },
        ],
      };

要注意:Black Sales 的 data 格式,和 Red Sales、Blue Sales 及 Yellow Sales 都不同。陣列裡面放的是物件,裡面 x 對應的是每一隻長條圖的 X 軸,y 則是折線圖每個數值的高度。

{
            label: "Black Sales",
            type: "line",
            order: 0,
            data: [
              { x: "2022-10-20", y: 1 },
              { x: "2022-10-20", y: 2 },
              { x: "2022-10-20", y: 3 },
              { x: "2022-10-21", y: 6 },
              { x: "2022-10-21", y: 9 },
              { x: "2022-10-21", y: 12 },
            ],
            backgroundColor: ["rgba(0, 0, 0, 0.2)"],
            borderColor: ["rgba(0, 0, 0, 1)"],
            borderWidth: 1,
          },

設定 lineAlignment 物件

lineAlignment 要放到 plugin 中,會在長條圖畫完之後,接著劃出點圖。

const lineAlignment = {
        id: "lineAlignment",
        afterDatasetsDraw(chart, args, pluginOptions) {
          //   console.log(chart.getDatasetMeta(0));
          const {
            scales: { x },
            data,
          } = chart;
          const lastDataset = data.datasets.length - 1;
          const xCoor = [];
          for (let i = 0; i < data.labels.length; i++) {
            // console.log(chart.getDatasetMeta(0).data[1].x)
            xCoor.push(chart.getDatasetMeta(0).data[i].x);
            xCoor.push(chart.getDatasetMeta(1).data[i].x);
            xCoor.push(chart.getDatasetMeta(2).data[i].x);

          }
          chart.getDatasetMeta(lastDataset).data.forEach((dataPoint,index) => {
            dataPoint.x = xCoor[index]  
            dataPoint.options.borderWidth = 0;          
          });
          console.log(chart.getDatasetMeta(lastDataset));
        },
      };

設定config

const config = {
        data,
        options: {
          scales: {
            x: {
              //   type: "time",
              //   time: {
              //     unit: "day",
              //   },
            },
            y: {
              beginAtZero: true,
            },
          },
        },
        plugins: [lineAlignment],
      };

畫圖

const myChart = new Chart(document.getElementById("myChart"), config);

相關文章

Leave a Reply

Your email address will not be published. Required fields are marked *