c6a95b0d |
import React from 'react';
import { withContentRect } from 'react-measure'
import { filter, range, map, pipe } from 'rambda';
import { ScatterChart, Scatter, XAxis, YAxis, CartesianGrid, Brush, Label } from 'recharts';
import Job from './Job';
import { maxTime, minTime } from '../ganttUtils';
import theme from '../theme';
class Gannt extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
startTime: minTime(props.data),
endTime: maxTime(props.data)
};
}
render() {
const { data, measureRef, contentRect: { bounds: dimensions } } = this.props;
const { startTime } = this.state;
const endTime = this.state.endTime === startTime ? startTime + 1 : this.state.endTime;
const scopeData = map(processorData =>
pipe(
filter(datum =>
(datum.startTime >= startTime
|| (datum.startTime < startTime && datum.endTime >= startTime)
)
&& datum.startTime <= endTime
),
map(datum => {
let newDatum = datum;
if (newDatum.startTime < startTime) {
newDatum = { ...newDatum, startTime, formerStartTime: newDatum.startTime };
}
if (newDatum.endTime > endTime) {
newDatum = { ...newDatum, endTime, formerEndTime: newDatum.endTime };
}
return newDatum;
})
)(processorData),
data
);
const processors = range(1, data.length + 1);
const scopeMinTime = minTime(scopeData);
const scopeMaxTime = maxTime(scopeData);
const ticksCountX = scopeMinTime + scopeMaxTime;
const width = Math.max(theme.gantt.maxWidth, dimensions.width);
const height = 100 + 1.75 * theme.gantt.job.height * processors.length;
const horizontalGuideLines = map(
i => theme.gantt.margin.top + i * 1.75 * theme.gantt.job.height - i * 10,
range(0, processors.length)
);
return (
<div ref={measureRef}>
<ScatterChart width={width} height={height} data={data[0]} margin={theme.gantt.margin}>
<CartesianGrid
stroke={theme.gantt.grid.stroke}
strokeDasharray="5 5"
horizontalPoints={horizontalGuideLines}
/>
<XAxis
type="number"
dataKey="startTime"
interval={0}
domain={[scopeMinTime, scopeMaxTime]}
tickCount={ticksCountX}
allowDecimals={false}
>
<Label offset={-30} position="insideBottom">Time</Label>
</XAxis>
<YAxis
type="number"
dataKey="processor"
interval={0}
name="processor"
allowDecimals={false}
domain={[0.5, processors.length + 0.5]}
ticks={processors}
>
<Label position="insideLeft" angle={-90}>Workers</Label>
</YAxis>
<Brush
dataKey="startTime"
y={height - theme.gantt.brush.height - 10}
height={theme.gantt.brush.height}
stroke={theme.gantt.brush.stroke}
onChange={({ startIndex, endIndex }) =>
this.setState({ startTime: startIndex + 1, endTime: endIndex + 1 })
}
/>
{scopeData.map((processorData, i) => (
<Scatter key={i} data={processorData} shape={<Job />} />
))}
</ScatterChart>
</div>
);
}
}
export default withContentRect('bounds')(Gannt); |