aboutsummaryrefslogtreecommitdiff
path: root/src/graph.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/graph.ts')
-rw-r--r--src/graph.ts85
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) };
+ });
+}