GridItem.jsx源码
/root/workspace/actionview/av-github-source-code/actionview-fe/app/components/gantt/GridItem.jsx
import React, { PropTypes, Component } from 'react';
import _ from 'lodash';
export default class GridItem extends Component {
constructor(props) {
super(props);
}
static propTypes = {
cellWidth: PropTypes.number.isRequired,
offset: PropTypes.number.isRequired,
clientWidth: PropTypes.number.isRequired,
dates: PropTypes.array.isRequired,
markedIssue: PropTypes.object.isRequired,
issue: PropTypes.object.isRequired,
today: PropTypes.string.isRequired
}
render() {
const {
cellWidth,
offset,
clientWidth,
dates,
markedIssue,
issue,
today=''
} = this.props;
const lsn = _.max([ _.floor(offset / cellWidth) - 15, 0 ]);
const ren = _.min([ _.floor((offset + clientWidth) / cellWidth) + 15, dates.length ]);
return (
<div
className='ganttview-grid-row'
style={ { width: dates.length * cellWidth + 'px' } }>
{ lsn > 0 &&
<div
className='ganttview-grid-row-cell'
style={ { width: cellWidth * lsn + 'px' } }/> }
{ _.map(dates.slice(lsn, ren), (v, key) =>
<div
className={ 'ganttview-grid-row-cell ' + (v.date == today ? 'ganttview-today' : (v.notWorking === 1 ? 'ganttview-weekend' : '')) }
style={ { backgroundColor: markedIssue.id == issue.id ? '#FFFACD' : '', width: cellWidth + 'px' } }
key={ v.date }/> ) }
{ dates.length - ren > 0 &&
<div
className='ganttview-grid-row-cell'
style={ { width: cellWidth * (dates.length - ren) + 'px' } }/> }
</div>);
}
}
源码解读
这段代码定义了一个名为 GridItem
的 React 组件,用于渲染甘特图中的一个网格行。甘特图是一种常用于项目管理和进度跟踪的时间线图表,它通过一系列水平条形图来表示任务的持续时间和进度。这个组件负责绘制甘特图中的一个行级网格,每个单元格代表一天或一段时间。
代码分析
导入模块
import React, { PropTypes, Component } from 'react';
import _ from 'lodash';
-
React
:React 的核心库。 -
PropTypes
:用于定义组件的 prop 类型检查。 -
lodash
:一个实用工具库,提供了很多常用的函数,如_.max
和_.min
。
定义组件类
export default class GridItem extends Component {
constructor(props) {
super(props);
}
-
GridItem
类继承自Component
,表示这是一个 React 组件。 -
constructor
构造函数初始化组件,并调用父类构造函数super(props)
来初始化父类属性。
定义 prop 类型
static propTypes = {
cellWidth: PropTypes.number.isRequired,
offset: PropTypes.number.isRequired,
clientWidth: PropTypes.number.isRequired,
dates: PropTypes.array.isRequired,
markedIssue: PropTypes.object.isRequired,
issue: PropTypes.object.isRequired,
today: PropTypes.string.isRequired
}
propTypes
是一个静态属性,用于定义组件接受的 prop 类型。
-
cellWidth
:每个单元格的宽度。 -
offset
:偏移量,表示绘制开始的位置。 -
clientWidth
:可见区域的宽度。 -
dates
:日期数组,每个对象包含日期信息。 -
markedIssue
:标记的问题对象。 -
issue
:当前行对应的问题对象。 -
today
:今天的日期字符串。
渲染方法
render() {
const {
cellWidth,
offset,
clientWidth,
dates,
markedIssue,
issue,
today=''
} = this.props;
const lsn = _.max([ _.floor(offset / cellWidth) - 15, 0 ]);
const ren = _.min([ _.floor((offset + clientWidth) / cellWidth) + 15, dates.length ]);
return (
<div
className='ganttview-grid-row'
style={ { width: dates.length * cellWidth + 'px' } }>
{ lsn > 0 &&
<div
className='ganttview-grid-row-cell'
style={ { width: cellWidth * lsn + 'px' } }/> }
{ _.map(dates.slice(lsn, ren), (v, key) =>
<div
className={ 'ganttview-grid-row-cell ' + (v.date == today ? 'ganttview-today' : (v.notWorking === 1 ? 'ganttview-weekend' : '')) }
style={ { backgroundColor: markedIssue.id == issue.id ? '#FFFACD' : '', width: cellWidth + 'px' } }
key={ v.date }/> ) }
{ dates.length - ren > 0 &&
<div
className='ganttview-grid-row-cell'
style={ { width: cellWidth * (dates.length - ren) + 'px' } }/> }
</div>);
}
}
render
方法返回组件的 JSX 结构。
- 解构赋值
const { ... } = this.props
来提取传入的 props。 - 计算
lsn
和ren
:
-
lsn
:左边界索引,计算从哪个单元格开始绘制。 -
ren
:右边界索引,计算绘制到哪个单元格结束。
- 渲染一个
<div>
容器,作为行级网格的基础。 - 如果
lsn
大于 0,则渲染一个占位的单元格,用于填充左边的空白区域。 - 使用
_.map
循环遍历dates
数组的子集(从lsn
到ren
),渲染每个日期对应的单元格。
- 单元格的类名根据今天是否为当前日期或是否为非工作日进行调整。
- 单元格的背景颜色根据
markedIssue
是否为当前issue
进行调整。
- 如果
dates.length - ren
大于 0,则渲染一个占位的单元格,用于填充右边的空白区域。
总结
这个 GridItem
组件负责渲染甘特图中的一个行级网格,其中包含若干个单元格,每个单元格代表一天或一段时间。组件根据传入的 props
动态计算网格的宽度和起始位置,并根据当前日期和任务状态调整单元格的样式。通过这种方式,组件能够灵活地适应不同的数据和布局需求,为用户提供清晰的任务进度视图。