aboutsummaryrefslogtreecommitdiff
path: root/src/Chart.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/Chart.js')
-rw-r--r--src/Chart.js113
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);