diff options
Diffstat (limited to 'src/graph.ts')
-rw-r--r-- | src/graph.ts | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/graph.ts b/src/graph.ts new file mode 100644 index 0000000..507b671 --- /dev/null +++ b/src/graph.ts @@ -0,0 +1,85 @@ +export type PatternGraphData = { + name: string, + value: number, + color: string +}; + +export type GraphData = { + name: string, + start: Date, + end: Date, + data: PatternGraphData +}; + +export function getGraphData(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) }; + }); +} |