You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中Chart.js折线图日期标签格式化方法咨询

解决方案:日期格式化与Chart.js标签规范处理

一、快速实现:直接格式化Labels

利用原生JS的Intl.DateTimeFormat可以直接在映射labels时转换日期格式,无需额外依赖。修改你的labels映射逻辑:

labels: post?.rates?.map((rate) => {
  const date = new Date(rate.effectiveDate);
  return new Intl.DateTimeFormat('en-US', {
    month: 'short', // 缩写月份(如Aug、Jul)
    day: 'numeric'  // 数字日期(如25、16)
  }).format(date);
}),

这种方式直接将API返回的日期字符串转为目标格式,适合固定显示格式的简单场景。

二、Chart.js规范格式化方法(推荐)

如果需要在图表的坐标轴刻度、提示框等不同区域统一或差异化处理日期格式,建议使用Chart.js的回调配置,这是官方推荐的标准做法:

1. 格式化X轴刻度

在options中配置scales.x.ticks.callback,自定义刻度显示:

options: {
  responsive: true,
  scales: {
    x: {
      ticks: {
        callback: function(value) {
          const rawDate = post?.rates[value]?.effectiveDate;
          if (!rawDate) return '';
          const date = new Date(rawDate);
          return new Intl.DateTimeFormat('en-US', {
            month: 'short',
            day: 'numeric'
          }).format(date);
        }
      }
    }
  }
}

2. 格式化提示框(Tooltip)日期

如果需要鼠标hover时的提示框也使用统一格式,可配置options.plugins.tooltip.callbacks.label:

options: {
  responsive: true,
  plugins: {
    tooltip: {
      callbacks: {
        label: function(context) {
          const rawDate = post?.rates[context.dataIndex]?.effectiveDate;
          const formattedDate = new Intl.DateTimeFormat('en-US', {
            month: 'short',
            day: 'numeric'
          }).format(new Date(rawDate));
          return `${formattedDate}: ${context.dataset.data[context.dataIndex]}`;
        }
      }
    }
  }
}

三、完整修改后的代码

整合上述方案,同时修复代码中缺失的导入和状态初始化问题:

import axios from 'axios';
import { useParams } from 'react-router-dom';
import { useState, useEffect } from 'react'; // 补充缺失的导入
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
} from 'chart.js';

import { Line } from 'react-chartjs-2';

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
);

const rate = axios.create({
  baseURL: 'http://api.nbp.pl/api/exchangerates/rates/a/',
});

const Chart = () => {
  const [post, setPost] = useState(null); // 初始化state为null,避免undefined报错
  const { id } = useParams();

  useEffect(() => {
    async function getPost() {
      try {
        const response = await rate.get(`/${id}/last/10/?format=json`);
        setPost(response.data);
      } catch (err) {
        console.error('获取数据失败:', err);
      }
    }
    getPost();
  }, [id]);

  // 处理数据加载状态
  if (!post) return <div>加载中...</div>;

  const data = {
    type: 'line',
    labels: post.rates.map((rate) => rate.effectiveDate), // 保留原始日期,通过Chart.js回调格式化
    datasets: [
      {
        label: `Ostatnie 10 odczytów`,
        data: post.rates.map((rate) => rate.mid),
        lineTension: 0.1,
        backgroundColor: 'rgba(15, 174, 150)',
        borderColor: 'rgba(15, 174, 150)',
        borderCapStyle: 'butt',
        borderDash: [],
        borderDashOffset: 0.0,
        borderJoinStyle: 'miter',
        pointBorderColor: 'rgba(15, 174, 150)',
        pointBackgroundColor: '#fff',
        pointBorderWidth: 1,
        pointHoverRadius: 5,
        pointHoverBackgroundColor: 'rgba(15, 174, 150)',
        pointHoverBorderColor: 'rgba(220,220,220,1)',
        pointHoverBorderWidth: 2,
        pointRadius: 1,
        pointHitRadius: 10,
      },
    ],
  };

  const options = {
    responsive: true,
    plugins: {
      tooltip: {
        callbacks: {
          label: (context) => {
            const rawDate = post.rates[context.dataIndex].effectiveDate;
            const formattedDate = new Intl.DateTimeFormat('en-US', {
              month: 'short',
              day: 'numeric'
            }).format(new Date(rawDate));
            return `${formattedDate}: ${context.dataset.data[context.dataIndex]}`;
          }
        }
      }
    },
    scales: {
      x: {
        ticks: {
          callback: (value) => {
            const rawDate = post.rates[value].effectiveDate;
            const date = new Date(rawDate);
            return new Intl.DateTimeFormat('en-US', {
              month: 'short',
              day: 'numeric'
            }).format(date);
          }
        }
      }
    }
  };

  return (
    <div
      style={{
        width: '800px',
        height: '800px',
        margin: '0 auto',
        paddingTop: '50px', // 调整padding避免内容过靠下
      }}
    >
      <Line data={data} options={options} />
    </div>
  );
};

export default Chart;

关键说明

  • Intl.DateTimeFormat是原生API,兼容性好,无需额外安装库;若需复杂日期处理,也可替换为moment.js或date-fns,用法逻辑一致。
  • Chart.js的回调配置更灵活,能统一管理图表各区域的日期格式,适合复杂业务场景。
  • 补充了状态初始化和加载状态处理,避免数据未加载时的报错。

内容的提问来源于stack exchange,提问作者Veronica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 00:18:30