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

如何将MM/YYYY日期转为月份名并实现BarChart多条件过滤?

解决方案

一、日期格式转换与图表显示修复

1. 日期字符串转月份名称

你用toString()无效是因为它仅转换字符串类型,未做格式解析。这里提供两种可靠转换方法:

方法一:使用Intl.DateTimeFormat(多语言友好)

// 定义转换函数
const formatMonthName = (dateStr) => {
  const [month, year] = dateStr.split('/');
  // 注意月份是0基,需减1
  const date = new Date(year, month - 1);
  // 格式化获取月份全称
  return new Intl.DateTimeFormat('en-US', { month: 'long' }).format(date);
};

方法二:手动定义月份数组(简单直接)

const monthNames = [
  'January', 'February', 'March', 'April', 'May', 'June',
  'July', 'August', 'September', 'October', 'November', 'December'
];

const formatMonthName = (dateStr) => {
  const monthIndex = parseInt(dateStr.split('/')[0], 10) - 1;
  return monthNames[monthIndex];
};

2. 修正数据处理与图表配置

你的代码中const [first_brewed, abv] = beers;存在解构错误——beers应为包含多个啤酒对象的数组,每个对象含first_brewed和abv字段。需先处理整个数组再传给图表:

方式A:提前处理数据(推荐,方便后续过滤)

// 处理原始beers数组,添加月份名称字段
const processedBeers = beers.map(beer => ({
  ...beer,
  monthName: formatMonthName(beer.first_brewed)
}));

// 图表中使用处理后的字段
return (
  <div className="bar-wrapper">
    <BarChart width={600} height={300} data={processedBeers}>
      <XAxis dataKey="monthName" stroke="#333" />
      <YAxis />
      <Tooltip />
      <CartesianGrid stroke="#ccc" strokeDasharray="5 5" />
      <Bar dataKey="abv" fill="#9772FB" barSize={30} />
    </BarChart>
  </div>
);

方式B:在XAxis中直接格式化(无需修改原数据)

若不想修改原数组,可通过XAxis的tickFormatter属性直接转换显示:

return (
  <div className="bar-wrapper">
    <BarChart width={600} height={300} data={beers}>
      <XAxis 
        dataKey="first_brewed" 
        stroke="#333"
        tickFormatter={(value) => formatMonthName(value)}
      />
      <YAxis />
      <Tooltip />
      <CartesianGrid stroke="#ccc" strokeDasharray="5 5" />
      <Bar dataKey="abv" fill="#9772FB" barSize={30} />
    </BarChart>
  </div>
);

二、复用BarChart实现双过滤功能

完全可以复用同一个BarChart组件,核心是维护过滤后的数据集状态,不管是日期还是ABV过滤,都更新该状态,图表始终接收过滤后的数据。

完整示例代码

import { useState } from 'react';
import { BarChart, XAxis, YAxis, Tooltip, CartesianGrid, Bar } from 'recharts';

// 日期转换函数
const formatMonthName = (dateStr) => {
  const [month, year] = dateStr.split('/');
  const date = new Date(year, month - 1);
  return new Intl.DateTimeFormat('en-US', { month: 'long' }).format(date);
};

const BeerChart = ({ initialBeers }) => {
  // 维护过滤后的数据集
  const [filteredBeers, setFilteredBeers] = useState(initialBeers);
  // 过滤条件状态
  const [selectedMonth, setSelectedMonth] = useState('');
  const [minAbv, setMinAbv] = useState('');
  const [maxAbv, setMaxAbv] = useState('');

  // 合并过滤逻辑
  const handleFilter = () => {
    let result = [...initialBeers];

    // 日期过滤(假设选择器返回月份名称,如"September")
    if (selectedMonth) {
      result = result.filter(beer => formatMonthName(beer.first_brewed) === selectedMonth);
    }

    // ABV范围过滤
    if (minAbv) {
      result = result.filter(beer => beer.abv >= parseFloat(minAbv));
    }
    if (maxAbv) {
      result = result.filter(beer => beer.abv <= parseFloat(maxAbv));
    }

    setFilteredBeers(result);
  };

  return (
    <>
      {/* 过滤控件 */}
      <div className="filters">
        <select value={selectedMonth} onChange={(e) => setSelectedMonth(e.target.value)}>
          <option value="">All Months</option>
          <option value="January">January</option>
          <option value="February">February</option>
          {/* 补充其他月份选项 */}
        </select>
        <input
          type="number"
          placeholder="Min ABV"
          value={minAbv}
          onChange={(e) => setMinAbv(e.target.value)}
        />
        <input
          type="number"
          placeholder="Max ABV"
          value={maxAbv}
          onChange={(e) => setMaxAbv(e.target.value)}
        />
        <button onClick={handleFilter}>Apply Filters</button>
      </div>

      {/* 复用的BarChart组件 */}
      <div className="bar-wrapper">
        <BarChart width={600} height={300} data={filteredBeers}>
          <XAxis 
            dataKey="first_brewed" 
            stroke="#333"
            tickFormatter={(value) => formatMonthName(value)}
          />
          <YAxis />
          <Tooltip 
            formatter={(value) => [`ABV: ${value}`, 'Alcohol By Volume']}
            labelFormatter={(label) => formatMonthName(label)}
          />
          <CartesianGrid stroke="#ccc" strokeDasharray="5 5" />
          <Bar dataKey="abv" fill="#9772FB" barSize={30} />
        </BarChart>
      </div>
    </>
  );
};

export default BeerChart;

关键说明

  • 用useState维护filteredBeers,所有过滤操作最终更新该状态
  • 过滤逻辑整合在handleFilter中,同时处理日期和ABV条件
  • BarChart始终接收filteredBeers作为数据源,无需修改组件本身

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:54:17