tonkean-react-calendar-timeline
Version:
react calendar timeline
82 lines (72 loc) • 2.43 kB
JavaScript
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import { iterateTimes } from '../utility/calendar'
export default class VerticalLines extends Component {
static propTypes = {
canvasTimeStart: PropTypes.number.isRequired,
canvasTimeEnd: PropTypes.number.isRequired,
canvasWidth: PropTypes.number.isRequired,
lineCount: PropTypes.number.isRequired,
minUnit: PropTypes.string.isRequired,
timeSteps: PropTypes.object.isRequired,
height: PropTypes.number.isRequired
}
shouldComponentUpdate(nextProps) {
return !(
nextProps.canvasTimeStart === this.props.canvasTimeStart &&
nextProps.canvasTimeEnd === this.props.canvasTimeEnd &&
nextProps.canvasWidth === this.props.canvasWidth &&
nextProps.lineCount === this.props.lineCount &&
nextProps.minUnit === this.props.minUnit &&
nextProps.timeSteps === this.props.timeSteps &&
nextProps.height === this.props.height
)
}
render() {
const {
canvasTimeStart,
canvasTimeEnd,
canvasWidth,
minUnit,
timeSteps,
height
} = this.props
const ratio = canvasWidth / (canvasTimeEnd - canvasTimeStart)
let lines = []
iterateTimes(
canvasTimeStart,
canvasTimeEnd,
minUnit,
timeSteps,
(time, nextTime) => {
const left = Math.round((time.valueOf() - canvasTimeStart) * ratio, -2)
const minUnitValue = time.get(minUnit === 'day' ? 'date' : minUnit)
const firstOfType = minUnitValue === (minUnit === 'day' ? 1 : 0)
const lineWidth = firstOfType ? 2 : 1
const labelWidth =
Math.ceil((nextTime.valueOf() - time.valueOf()) * ratio) - lineWidth
const leftPush = firstOfType ? -1 : 0
const classNames =
'rct-vl' +
(firstOfType ? ' rct-vl-first' : '') +
(minUnit === 'day' || minUnit === 'hour' || minUnit === 'minute'
? ` rct-day-${time.day()}`
: '')
lines.push(
<div
key={`line-${time.valueOf()}`}
className={classNames}
style={{
pointerEvents: 'none',
top: '0px',
left: `${left + leftPush}px`,
width: `${labelWidth}px`,
height: `${height}px`
}}
/>
)
}
)
return <div className="rct-vertical-lines">{lines}</div>
}
}