From c594888953151ddfb4ca04b7752bfd51edc1d6da Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 13 Feb 2019 01:11:31 -0500 Subject: WIP: migrate to TypeScriptX --- src/Chart.tsx | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 src/Chart.tsx (limited to 'src/Chart.tsx') diff --git a/src/Chart.tsx b/src/Chart.tsx new file mode 100644 index 0000000..b1c36ed --- /dev/null +++ b/src/Chart.tsx @@ -0,0 +1,165 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import Grid from '@material-ui/core/Grid'; +import cyan from '@material-ui/core/colors/cyan'; +import { PieChart, Pie, Cell, Tooltip } from 'recharts'; +import { defaultChartColor } from './theme'; + +export function getChartData(start, end, patterns, calendars, calEventsGetter) { + if (start >= end) return Promise.resolve({ patternGraphData: [], calendarGraphData: [] }); + let event_pms = []; + for (let id in calendars) + { + if (!calendars[id].enabled) continue; + 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: defaultChartColor, + }); + return majorParts; + }; + for (let i = 0; i < patterns.length; i++) { + patternGraphData.push({ + name: patterns[i].name, + value: results[i] / 60.0, + color: patterns[i].color.background}); + } + 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', + } +}); + +function customizedLabel(props) { + const {cx, cy, x, y, fill, name} = props; + let anchor = "middle"; + const EPS = 2; + let dx = 0; + let dy = 0; + if (x < cx - EPS) { + dx = -5; + anchor = "end" + } else if (x > cx + EPS) { + dx = 5; + anchor = "start"; + } + + if (y < cy - EPS) { + dy = -5; + } else if (y > cy + EPS) { + dy = 10; + } + + return ({`${name}`}); +} + +function PatternPieChart(props) { + return ( + +
+ + + {props.data.map((d, i) => )} + + `${value.toFixed(2)} hr`}/> + +
+
+ ); +} + +export const StyledPatternPieChart = withStyles(styles)(PatternPieChart); + +function DoublePieChart(props) { + return ( + + + +
+ + + {props.calendarGraphData.map((d, i) => )} + + `${value.toFixed(2)} hr`}/> + +
+
+
); +} + +DoublePieChart.propTypes = { + patternGraphData: PropTypes.array.isRequired, + calendarGraphData: PropTypes.array.isRequired, +}; + +export const AnalyzePieChart = withStyles(styles)(DoublePieChart); -- cgit v1.2.3