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

如何用Recharts制作含间断区间的事件时序水平条形图?

使用Recharts实现带断开区间的事件时序水平条形图

完全可以用Recharts实现你描述的需求,下面是具体实现方案:

1. 数据预处理

首先需要给事件补充团队标识(对应每个条形代表的团队),并将时间字符串转换为时间戳,方便计算条形的起始位置和宽度:

const eventData = [
  {
    from: new Date("2023-04-30T00:00:00.000Z").getTime(),
    to: new Date("2023-05-01T00:00:00.000Z").getTime(),
    message: "Code Freeze",
    team: "Team A"
  },
  {
    from: new Date("2023-05-05T00:00:00.000Z").getTime(),
    to: new Date("2023-05-10T00:00:00.000Z").getTime(),
    message: "Mother's Day Sale",
    team: "Team A"
  },
  {
    from: new Date("2023-05-10T00:00:00.000Z").getTime(),
    to: new Date("2023-05-15T00:00:00.000Z").getTime(),
    message: "Holiday Party",
    team: "Team B"
  }
];

2. 完整实现代码

通过BarChart+Bar组件实现,核心是自定义每个条形的起始位置和宽度,同时配置时间轴、交替颜色和提示框:

import React from 'react';
import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';

const EventTimelineChart = () => {
  const eventData = [
    {
      from: new Date("2023-04-30T00:00:00.000Z").getTime(),
      to: new Date("2023-05-01T00:00:00.000Z").getTime(),
      message: "Code Freeze",
      team: "Team A"
    },
    {
      from: new Date("2023-05-05T00:00:00.000Z").getTime(),
      to: new Date("2023-05-10T00:00:00.000Z").getTime(),
      message: "Mother's Day Sale",
      team: "Team A"
    },
    {
      from: new Date("2023-05-10T00:00:00.000Z").getTime(),
      to: new Date("2023-05-15T00:00:00.000Z").getTime(),
      message: "Holiday Party",
      team: "Team B"
    }
  ];

  // 自定义Tooltip内容
  const CustomTooltip = ({ active, payload }) => {
    if (active && payload && payload.length) {
      const data = payload[0].payload;
      return (
        <div style={{ backgroundColor: '#fff', padding: '8px', border: '1px solid #ccc' }}>
          <p>{data.message}</p>
          <p>时间区间: {new Date(data.from).toLocaleDateString()} 至 {new Date(data.to).toLocaleDateString()}</p>
        </div>
      );
    }
    return null;
  };

  // 获取所有时间点,用于X轴范围计算
  const allTimestamps = eventData.flatMap(item => [item.from, item.to]);
  const minTimestamp = Math.min(...allTimestamps);
  const maxTimestamp = Math.max(...allTimestamps);

  return (
    <ResponsiveContainer width="100%" height={300}>
      <BarChart
        data={eventData}
        layout="horizontal"
        margin={{ top: 20, right: 30, left: 40, bottom: 20 }}
        barSize={20}
      >
        <XAxis
          type="number"
          domain={[minTimestamp - 86400000, maxTimestamp + 86400000]} // 前后各加一天留白
          tickFormatter={(timestamp) => new Date(timestamp).toLocaleDateString()}
        />
        <YAxis type="category" dataKey="team" />
        <Tooltip content={<CustomTooltip />} />
        {eventData.map((item, index) => (
          <Bar
            key={index}
            x={item.from}
            width={item.to - item.from}
            y={item.team}
            fill={index % 2 === 0 ? '#8884d8' : '#82ca9d'}
            dataKey="team"
          />
        ))}
      </BarChart>
    </ResponsiveContainer>
  );
};

export default EventTimelineChart;

关键实现细节说明

  • 断开区间处理:通过给每个Bar设置x为事件起始时间戳,width为结束时间与起始时间的差值,实现条形在时间轴上的精准定位,自然形成空白断开区域。
  • 交替颜色:利用数组索引取模,给奇偶位置的条形设置不同填充色。
  • 时间轴配置:将X轴设置为数值型,通过tickFormatter将时间戳转换为可读的日期格式,同时扩展轴范围增加留白。
  • 自定义提示框:通过CustomTooltip组件展示事件描述和时间区间,满足悬停提示需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 08:12:38