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

React中多数据源Rechart图表X轴标签升序排序问题求解

问题核心原因

Recharts默认按数据集传入的顺序渲染X轴分类标签,两个数据源的hour字段顺序不一致、或是原始数据本身hour为乱序时,就会出现X轴标签排序异常的问题。

解决方案

步骤1:预处理所有数据集按hour升序排序

先对两个来源的每个分类数据集按hour统一排序,保证所有数据源的条目顺序一致:

// 预处理数据:将每个来源的每个分类数据按hour升序排序
const sortedSeries = series.map(source => {
  const sortedCategoryData = Object.fromEntries(
    Object.entries(source.data).map(([category, dataList]) => {
      // 若hour为数字格式直接排序,时分字符串格式的排序逻辑见下方补充
      const sorted = [...dataList].sort((a, b) => Number(a.hour) - Number(b.hour))
      return [category, sorted]
    })
  )
  return {...source, data: sortedCategoryData}
})

步骤2:(可选,更稳妥)手动指定X轴排序后的标签

如果不同数据源可能存在hour缺失的情况,可以手动收集所有hour值排序后传给XAxis的ticks属性,强制X轴按指定顺序渲染:

// 收集当前分类下所有来源的hour值,去重后排序
const getSortedHours = (category) => {
  const allHours = new Set()
  series.forEach(source => {
    source.data[category]?.forEach(item => allHours.add(item.hour))
  })
  return Array.from(allHours).sort((a, b) => Number(a) - Number(b))
}

最终修改渲染代码

替换原渲染逻辑中的series为预处理后的sortedSeries,给XAxis增加ticks属性即可:

selectedCategories.map((category, i) => (
  <ResponsiveContainer height={350} width='50%' key={category}>
    <LineChart
      margin={{ top: 40, right: 30, left: 70, bottom: 5 }}
      syncId='category'
    >
      <XAxis 
        dataKey='hour' 
        allowDuplicatedCategory={false}
        ticks={getSortedHours(category)}
      />
      <YAxis
        label={{
          value: category,
          position: 'top',
          fontSize: 18,
          offset: 20,
          fontWeight: 'bold',
          fill: COLORS[i % 8]
        }}
        tickFormatter={formatUSD}
      />
      <CartesianGrid strokeDasharray='3 3' />
      <Tooltip formatter={formatUSD} />
      {sortedSeries.map((s, i) => (
        <Line dataKey='rpc' stroke={COLORS[i % 2]} data={s.data[category]} name={s.name} key={s.name} />
      ))}
      <ReferenceArea y2={0} stroke='red' color='red' strokeOpacity={0.5} />
    </LineChart>
  </ResponsiveContainer>
))

补充:如果hour是时分字符串格式(如09:30)

替换排序逻辑为按时分总分钟数排序即可:

.sort((a, b) => {
  const [aHour, aMinute] = a.hour.split(':').map(Number)
  const [bHour, bMinute] = b.hour.split(':').map(Number)
  return (aHour * 60 + aMinute) - (bHour * 60 + bMinute)
})

内容的提问来源于stack exchange,提问作者wokoro douye samuel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 10:12:00