将 chart.js 的 x 轴标签格式化

7
我使用React和chart.js。我的问题是如何每个月只显示一个月份标签(MMM)?
目前图表的标签为:[May 15, May 18, May 21, May 24, ...]
结果希望得到:[May 15, 18, 21, 24, 27, 30, Jun 2, 5, ...]

CodeSandbox

enter image description here

折线图:
import React from 'react'
import { Line } from 'react-chartjs-2'
import date from 'date-and-time'

const startDate = new Date(2020, 4, 15)

//===fake data===
const json = '{"responses":[{"rows":[{"values":["1"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["1"]},{"values":["6"]},{"values":["7"]},{"values":["5"]},{"values":["8"]},{"values":["9"]},{"values":["2"]},{"values":["1"]},{"values":["1"]},{"values":["1"]},{"values":["6"]},{"values":["3"]},{"values":["0"]},{"values":["20"]},{"values":["9"]},{"values":["3"]},{"values":["2"]},{"values":["1"]},{"values":["13"]},{"values":["3"]},{"values":["13"]},{"values":["13"]},{"values":["7"]},{"values":["12"]},{"values":["0"]}]}]}'
const values = JSON.parse(json).responses[0].rows.map((row, index) => {
  let date = new Date(2020, 4, 20)
  date.setDate(startDate.getDate() + index)
  return {
    y: row.values[0],
    x: date,
  }
})
//===============

const options = {
  legend: {
    display: false,
  },
  hover: {
    mode: 'index',
    intersect: false,
    animationDuration: 0,
  },
  scales: {
    yAxes: [{ position: 'right' }],
    xAxes: [{
      gridLines: { display: false },
      distribution: 'linear',
      type: 'time',
      time: {
        parser: 'MMM D',
        tooltipFormat: 'MMM D',
        unit: 'day',
        unitStepSize: 3,
        displayFormats: {
          day: 'MMM D',
        },
      },
      ticks: {
        min: startDate,
        max: date.format(date.addDays(new Date(), 1), 'MMM D'),
        autoSkip: true
      },
    }],
  },
  tooltips: {
    mode: 'x-axis',
  },
}

const data = {
  datasets: [
    {
      label: 'test',
      fill: false,
      data: values,
      backgroundColor: '#fff',
      borderWidth: 2,
      lineTension: 0,
      borderColor: 'forestgreen',
      hoverBorderWidth: 2,
      pointBorderColor: 'rgba(0, 0, 0, 0)',
      pointBackgroundColor: 'rgba(0, 0, 0, 0)',
      pointHoverBackgroundColor: '#fff',
      pointHoverBorderColor: 'forestgreen',
      showLine: true,
    }
  ],
}

const LineChart = () => <Line data={data} options={options}/>

export default LineChart
2个回答

3
解决方案1标签过滤器: 根据“过滤标签示例”,可以设置一个函数来定义应该显示什么。 (filtering labels sample)
options: {
    scales: {
        x: {
            display: true,
            ticks: {
                callback: function(dataLabel, index) {
                    // Apply logic to remove name of the month
                    return dataLabel
                }
            }
        },
        y: {
            display: true,
            beginAtZero: false
        }
    }
}

该示例的Github源代码

解决方案2: 您可以预先准备标签数组。过滤所有即将出现的提及并将此数组馈送给chart.js。


我最终得到了类似于callback: function (label, index){ }来自Chart.js/src/core/core.scale.js#L157 - Njuguna Mureithi
1
你已经提供了示例,但问题仍然存在,很可能没有本地解决方案,即使您编写自定义代码,当图表调整大小时,您还需要再次调用 ticks.callback - Arthur

1
  1. daymonth定义不同的displayFormats
  2. 启用ticks.major
  3. 通过afterBuildTicks回调将所需的刻度标记为major
time: {
  ...
  displayFormats: {
    day: 'D',
    month: 'MMM D',
  },
},
ticks: {
  major: {
    enabled: true
  }
},
afterBuildTicks: (scale, ticks) => {
  ticks.forEach((t, i) => t.major = i == 0 || new Date(t.value).getMonth() != new Date(ticks[i - 1].value).getMonth());
  return ticks;
}

请查看您修改后的代码,看看它是如何工作的。

const startDate = new Date(2020, 4, 15)

//===fake data===
const json = '{"responses":[{"rows":[{"values":["1"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["0"]},{"values":["1"]},{"values":["6"]},{"values":["7"]},{"values":["5"]},{"values":["8"]},{"values":["9"]},{"values":["2"]},{"values":["1"]},{"values":["1"]},{"values":["1"]},{"values":["6"]},{"values":["3"]},{"values":["0"]},{"values":["20"]},{"values":["9"]},{"values":["3"]},{"values":["2"]},{"values":["1"]},{"values":["13"]},{"values":["3"]},{"values":["13"]},{"values":["13"]},{"values":["7"]},{"values":["12"]},{"values":["0"]}]}]}'
const values = JSON.parse(json).responses[0].rows.map((row, index) => {
  let date = new Date(2020, 4, 20);
  date.setDate(startDate.getDate() + index)
  return {
    y: row.values[0],
    x: date
  }
})

//===============

const options = {
  legend: {
    display: false
  },
  hover: {
    mode: 'index',
    intersect: false,
    animationDuration: 0
  },
  scales: {
    yAxes: [{
      position: 'right'
    }],
    xAxes: [{
      gridLines: {
        display: false
      },
      distribution: 'linear',
      type: 'time',
      time: {
        tooltipFormat: 'MMM D',
        unit: 'day',
        unitStepSize: 3,
        displayFormats: {
          day: 'D',
          month: 'MMM D',
        },
      },
      ticks: {
        major: {
          enabled: true
        }
      },
      afterBuildTicks: (scale, ticks) => {
        ticks.forEach((t, i) => t.major = i == 0 || new Date(t.value).getMonth() != new Date(ticks[i - 1].value).getMonth());
        return ticks;
      }
    }]
  },
  tooltips: {
    mode: 'x-axis',
  }
};

const data = {
  datasets: [{
    label: 'test',
    fill: false,
    data: values,
    backgroundColor: '#fff',
    borderWidth: 2,
    lineTension: 0,
    borderColor: 'forestgreen',
    hoverBorderWidth: 2,
    pointBorderColor: 'rgba(0, 0, 0, 0)',
    pointBackgroundColor: 'rgba(0, 0, 0, 0)',
    pointHoverBackgroundColor: '#fff',
    pointHoverBorderColor: 'forestgreen',
    showLine: true,
  }],
};

new Chart('myChart', {
  type: 'line',
  data: data,
  options: options
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="myChart" height="90"></canvas>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接