diff options
Diffstat (limited to 'src/Chart.js')
-rw-r--r-- | src/Chart.js | 113 |
1 files changed, 96 insertions, 17 deletions
diff --git a/src/Chart.js b/src/Chart.js index b41b17e..88ab72c 100644 --- a/src/Chart.js +++ b/src/Chart.js @@ -6,6 +6,75 @@ import deepOrange from '@material-ui/core/colors/deepOrange'; import cyan from '@material-ui/core/colors/cyan'; import { PieChart, Pie, Cell, Tooltip } from 'recharts'; +export function getChartData(start, end, patterns, calendars, calEventsGetter) { + if (start >= end) return Promise.resolve({ patternGraphData: [], calendarGraphData: [] }); + let event_pms = []; + for (let id in calendars) + { + let filtered = patterns.filter(p => p.cal.regex.test(calendars[id].name)); + if (filtered.length > 0) + event_pms.push(calEventsGetter(id, start, end) + .then(r => { return { id, events: r, filtered }; })); + } + return Promise.all(event_pms).then(all_events => { + let events = {}; + let patternsByCal = {}; + let results = {}; // pattern idx => time + let cal_results = {}; // cal id => time + all_events.forEach(e => { + events[e.id] = e.events; + patternsByCal[e.id] = e.filtered; + }); + for (let i = 0; i < patterns.length; i++) + results[i] = 0; + for (let id in calendars) { + if (!events[id]) continue; + events[id].forEach(event => { + patternsByCal[id].forEach(p => { + if (!p.event.regex.test(event.summary)) return; + if (!cal_results.hasOwnProperty(id)) { + cal_results[id] = 0; + } + let duration = (event.end - event.start) / 60000; + results[p.idx] += duration; + cal_results[id] += duration; + }); + }); + } + let patternGraphData = []; + let calendarGraphData = []; + const filterMarginal = data => { + let sum = 0; + let majorParts = []; + let minorSum = 0; + data.forEach(d => sum += d.value); + data.forEach(d => { + let ratio = d.value / sum; + if (ratio < 1e-2) minorSum += d.value; + else majorParts.push(d); + }); + majorParts.push({ + name: 'Other', + value: minorSum, + color: '#fff', + }); + return majorParts; + }; + for (let i = 0; i < patterns.length; i++) { + patternGraphData.push({ name: patterns[i].name, value: results[i] / 60.0 }); + } + for (let id in cal_results) { + calendarGraphData.push({ + name: calendars[id].name, + value: (cal_results[id] / 60.0), + color: calendars[id].color.background}); + } + return {start, end, + patternGraphData: filterMarginal(patternGraphData), + calendarGraphData: filterMarginal(calendarGraphData) }; + }); +} + const styles = theme => ({ pieChart: { margin: '0 auto', @@ -35,23 +104,32 @@ function customizedLabel(props) { return (<text x={x} y={y} dx={dx} dy={dy} fill={fill} textAnchor={anchor}>{`${name}`}</text>); } -function ChromiclePieChart(props) { +function PatternPieChart(props) { + return ( + <Grid item xs={12} lg={6}> + <div className={props.classes.patternTableWrapper}> + <PieChart width={400} height={250} className={props.classes.pieChart}> + <Pie data={props.data} + dataKey='value' + cx={200} + cy={125} + outerRadius={60} + fill={deepOrange[300]} + isAnimationActive={false} + label={customizedLabel}/> + <Tooltip formatter={(value) => `${value.toFixed(2)} hr`}/> + </PieChart> + </div> + </Grid> + ); +} + +export const StyledPatternPieChart = withStyles(styles)(PatternPieChart); + +function DoublePieChart(props) { return ( <Grid container spacing={0}> - <Grid item xs={12} lg={6}> - <div className={props.classes.patternTableWrapper}> - <PieChart width={400} height={250} className={props.classes.pieChart}> - <Pie data={props.patternGraphData} - dataKey='value' - cx={200} - cy={125} - outerRadius={60} - fill={deepOrange[300]} - label={customizedLabel}/> - <Tooltip formatter={(value) => `${value.toFixed(2)} hr`}/> - </PieChart> - </div> - </Grid> + <StyledPatternPieChart data={props.patternGraphData} /> <Grid item xs={12} lg={6}> <div className={props.classes.patternTableWrapper}> <PieChart width={400} height={250} className={props.classes.pieChart}> @@ -62,6 +140,7 @@ function ChromiclePieChart(props) { innerRadius={40} outerRadius={70} fill={cyan[300]} + isAnimationActive={false} label={customizedLabel}> {props.calendarGraphData.map((d, i) => <Cell key={i} fill={d.color}/>)} </Pie> @@ -72,9 +151,9 @@ function ChromiclePieChart(props) { </Grid>); } -ChromiclePieChart.propTypes = { +DoublePieChart.propTypes = { patternGraphData: PropTypes.array.isRequired, calendarGraphData: PropTypes.array.isRequired, }; -export default withStyles(styles)(ChromiclePieChart); +export const AnalyzePieChart = withStyles(styles)(DoublePieChart); |