在 chart.js 中使用带有月份和年份的自定义 x 轴绘制条形图时出现问题

Issue while plotting bar chart with custom x-axis with month and year in chart.js

我们正在尝试使用 chart.js 绘制条形图,并希望在 x 轴上显示月份和年份,但无法这样做。

我们要绘制如下图的柱状图:

https://drive.google.com/file/d/1ezvUdDyp3uNLP3pdumXKHcXGNeBVQw63/view

代码片段:

var timeFormat = 'DD/MM/YYYY';
var data = [
  { date: "1/1/2020  11:35:44 PM", file: "file1", value: 0.0056 },
  { date: "1/1/2020 23:35", file: "file2", value: 0.00103 },
  { date: "1/1/2020 23:35", file: "file3", value: 0.00513 },
  { date: "1/1/2020 23:59", file: "file4", value: 0.00589 },
  { date: "3/2/2020 0:24", file: "file5", value: 0.03017 },
  { date: "3/2/2020 0:30", file: "file6", value: 0.00347 },
  { date: "3/2/2020 0:43", file: "file7", value: 0.00784 },
  { date: "5/2/2020 0:51", file: "file8", value: 0.02477 },
  { date: "5/2/2020 1:08", file: "file9", value: 0.00858 },
  { date: "8/2/2020 2:03", file: "file10", value: 0.00753 },
  { date: "8/2/2020 2:36", file: "file11", value: 0.0091 },
  { date: "1/2/2021 4:38", file: "file12", value: 0.01175 },
  { date: "2/4/2021 5:15", file: "file13", value: 0.01092 }
];

var ctx = document.getElementById("CanvasFileData").getContext('2d');
var myChart = new Chart(ctx, {
  type: 'bar',
  data: data,
  options: {
    responsive: true,
    title: {
      display: true,
      text: "File data"
    },
    scales: {
      xAxes: [{
        type: "time",
        time: {
          format: timeFormat,
          tooltipFormat: 'll'
        },
        scaleLabel: {
          display: true,
          labelString: 'Date'
        }
      }],
      yAxes: [{
        scaleLabel: {
          display: true,
          labelString: 'value'
        },
        ticks: {
          beginAtZero: true
        }
      }]
    },
    tooltips: {
      callbacks: {
        label: function(tooltipItem) {
          return "File: " + tooltipItem.file + ", Date:" + tooltipItem.date + ", Value:" + tooltipItem.value;
        }
      }
    }
  }
});
<canvas id="CanvasFileData" style="width: 100%"></canvas>

您的文件栏应均匀分布在 x 轴上可用的 space 上。在此上下文中使用时间轴不是一种选择,因为它不会正确匹配条形的位置。

需要时间来详细解释所有内容才能获得您要查找的内容。因此,您最好研究下面的可运行代码,看看它是如何完成的。

var data = [
  { date: "1/1/2020  11:35:44 PM", file: "file1", value: 0.0056 },
  { date: "1/1/2020 23:35", file: "file2", value: 0.00103 },
  { date: "1/1/2020 23:35", file: "file3", value: 0.00513 },
  { date: "1/1/2020 23:59", file: "file4", value: 0.00589 },
  { date: "3/2/2020 0:24", file: "file5", value: 0.03017 },
  { date: "3/2/2020 0:30", file: "file6", value: 0.00347 },
  { date: "3/2/2020 0:43", file: "file7", value: 0.00784 },
  { date: "5/2/2020 0:51", file: "file8", value: 0.02477 },
  { date: "5/2/2020 1:08", file: "file9", value: 0.00858 },
  { date: "8/2/2020 2:03", file: "file10", value: 0.00753 },
  { date: "8/2/2020 2:36", file: "file11", value: 0.0091 },
  { date: "1/2/2021 4:38", file: "file12", value: 0.01175 },
  { date: "2/4/2021 5:15", file: "file13", value: 0.01092 }
];
const moments = data.map(o => moment(o.date, 'M/D/YYYY'));
const months = moments.map(m => m.format('MMM'));
const monthLabels = months.map((m, i) => i == 0 || months[i - 1] != m ? m : '〃');
const years = moments.map(m => m.format('YYYY'));
const yearLabels = years.map((y, i) => i == 0 || years[i - 1] != y ? y : '');

new Chart('CanvasFileData', {
  type: 'bar',
  data: {
    labels: data.map(o => o.file),
    datasets: [{
      data: data.map(o => o.value),
      backgroundColor: 'rgb(68, 114, 196)',
      barPercentage: 0.5
    }]
  },
  options: {
    responsive: true,
    title: {
      display: true,
      text: "File data"
    },
    legend: {
      display: false
    },
    scales: {
      xAxes: [{
        ticks: {
          minRotation: 90,
          padding: -32
        },
        gridLines: {
          drawOnChartArea: false,
          tickMarkLength: 40
        }
      },
      {
        offset: true,
        labels: monthLabels,
        gridLines: {
          display: false
        },   
      },
      {
        offset: true,
        labels: yearLabels,
        gridLines: {
          display: false
        },
        scaleLabel: {
          display: true,
          labelString: 'Date'
        }        
      }],
      yAxes: [{
        scaleLabel: {
          display: true,
          labelString: 'value'
        },
        ticks: {
          beginAtZero: true
        }
      }]
    },
    tooltips: {
      callbacks: {
        label: tooltipItem => "File: " + tooltipItem.xLabel + ", Date:" + data[tooltipItem.index].date + ", Value:" + tooltipItem.value
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="CanvasFileData" height="150"></canvas>