使用react实现一个甘特图组件
时间: 2024-01-22 22:20:55 浏览: 32
好的,以下是一个简单的甘特图组件的 React 实现:
```javascript
import React from 'react';
class GanttChart extends React.Component {
render() {
const { tasks } = this.props;
// 计算每个任务的开始和结束时间
let minDate = new Date();
let maxDate = new Date(0);
tasks.forEach(task => {
if (task.startDate < minDate) {
minDate = task.startDate;
}
if (task.endDate > maxDate) {
maxDate = task.endDate;
}
});
// 计算总时间范围和每个任务的时间范围
const totalDays = Math.floor((maxDate - minDate) / (1000 * 60 * 60 * 24));
const taskDays = tasks.map(task => ({
name: task.name,
days: Math.floor((task.endDate - task.startDate) / (1000 * 60 * 60 * 24)),
startOffset: Math.floor((task.startDate - minDate) / (1000 * 60 * 60 * 24)),
}));
// 计算每个任务的位置和宽度
const taskWidth = 100 / totalDays;
const taskBars = taskDays.map(task => ({
name: task.name,
left: task.startOffset * taskWidth,
width: task.days * taskWidth,
}));
return (
<div className="gantt-chart">
<div className="gantt-chart-header">
{Array.from({ length: totalDays }, (_, i) => (
<div key={i} className="gantt-chart-day">
{new Date(minDate.getTime() + i * 24 * 60 * 60 * 1000).getDate()}
</div>
))}
</div>
<div className="gantt-chart-body">
{taskBars.map(task => (
<div key={task.name} className="gantt-chart-task" style={{ left: `${task.left}%`, width: `${task.width}%` }}>
{task.name}
</div>
))}
</div>
</div>
);
}
}
export default GanttChart;
```
这个组件的基本思路是,首先遍历所有任务,计算出每个任务的开始和结束时间,并且找到时间范围的最小值和最大值。接着根据时间范围计算出总共有多少天,以及每个任务的时间范围和在时间轴上的位置和宽度。最后通过 CSS 样式将任务在甘特图上进行展示。
使用该组件时,需要传入一个任务列表,每个任务包含名称、开始时间和结束时间等属性。例如:
```javascript
<GanttChart
tasks={[
{ name: '任务1', startDate: new Date('2022-01-01'), endDate: new Date('2022-01-05') },
{ name: '任务2', startDate: new Date('2022-01-06'), endDate: new Date('2022-01-10') },
{ name: '任务3', startDate: new Date('2022-01-11'), endDate: new Date('2022-01-15') },
]}
/>
```
该组件的样式需要根据实际需求进行调整,可以参考以下示例:
```css
.gantt-chart {
border: 1px solid #ccc;
border-radius: 4px;
overflow: hidden;
}
.gantt-chart-header {
display: flex;
}
.gantt-chart-day {
width: calc(100% / 7);
padding: 8px;
text-align: center;
font-size: 12px;
font-weight: bold;
color: #999;
background-color: #f5f5f5;
border-right: 1px solid #ccc;
}
.gantt-chart-body {
display: flex;
}
.gantt-chart-task {
position: relative;
height: 30px;
line-height: 30px;
padding: 0 8px;
font-size: 12px;
font-weight: bold;
color: #fff;
background-color: #007bff;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
```