From ce227c5be46b237b7ff0d5d642e8a71ccaff74f6 Mon Sep 17 00:00:00 2001 From: svxf Date: Thu, 27 Dec 2018 14:44:21 +0400 Subject: [PATCH] more graphs --- templates/web/user_detail.html | 8 +++- web/chart_views.py | 71 +++++++++++++++++++++++++++------- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/templates/web/user_detail.html b/templates/web/user_detail.html index 3735d6a..66ee383 100644 --- a/templates/web/user_detail.html +++ b/templates/web/user_detail.html @@ -14,6 +14,12 @@

{{ user }}

+
+
+ +
+
+
@@ -77,8 +83,6 @@
- -

Активности

    {% for activities_and_pct in activities_and_pcts %} diff --git a/web/chart_views.py b/web/chart_views.py index 8fb266b..a28a411 100644 --- a/web/chart_views.py +++ b/web/chart_views.py @@ -13,16 +13,9 @@ class UserChartsPie(DetailView): model = User pk_url_kwarg = 'user_id' - def render_to_response(self, context, **response_kwargs): - import matplotlib - matplotlib.use('Agg') - import matplotlib.pyplot as plt - fig = plt.figure(figsize=(6, 6), dpi=100) - ax = fig.add_subplot(111) - + def pie_chart(self, plt, ax, logs): total_time = defaultdict(float) - logs = ActivityLog.objects.filter(user=self.object).all() for log in logs: total_time[str(log.activity)] += (log.end_time - log.start_time).total_seconds() @@ -30,6 +23,51 @@ class UserChartsPie(DetailView): ax.pie(x=[i[1] for i in sectors], labels=[i[0] for i in sectors], autopct='%1.0f%%') + def average_chart(self, plt, ax, logs): + interval = timedelta(minutes=10) + interval_count = timedelta(days=1) // interval + intervals = [(interval * i) / timedelta(hours=1) for i in range(interval_count)] + + distr_by_activity = {} + for i in logs: + if i.activity not in distr_by_activity: + distr_by_activity[i.activity] = np.zeros(interval_count) + + for i in logs: + day = i.start_time.replace(hour=0, minute=0, second=0, microsecond=0) + + t = i.start_time + t_i = (t - day) // interval + + while t < i.end_time: + distr_by_activity[i.activity][t_i] += 1 + + t += interval + t_i = (t_i + 1) % interval_count + + for activity, distr in distr_by_activity.items(): + ax.plot(intervals, distr, label=f'{activity}') + + distr[0] = 0 + distr[-1] = 0 + ax.fill(intervals, distr, alpha=0.2) + + plt.legend() + + def render_to_response(self, context, **response_kwargs): + logs = ActivityLog.objects.filter(user=self.object).all() + + import matplotlib + matplotlib.use('Agg') + import matplotlib.pyplot as plt + fig = plt.figure(figsize=(12, 16), dpi=100) + + ax = fig.add_subplot(221) + self.pie_chart(plt, ax, logs) + + ax = fig.add_subplot(212) + self.average_chart(plt, ax, logs) + buf = io.BytesIO() fig.savefig(buf, format='png') b = buf.getvalue() @@ -84,30 +122,33 @@ class UserChartsActivityAll(DetailView): plt.yticks(days, [f'{i:%m-%d}' for i in days]) plt.grid(True, zorder=1) - def render_to_response(self, context, **response_kwargs): - logs = list(ActivityLog.objects.filter(user=self.object, activity=context['activity']).order_by('start_time').all()) + def average_chart(self, plt, ax, logs, day_l, day_r, day_count, days): + pass + def render_to_response(self, context, **response_kwargs): + logs = ActivityLog.objects.filter(user=self.object).all() day_r = logs[-1].end_time.replace(hour=0, minute=0, second=0, microsecond=0) day_l = max( logs[0].start_time.replace(hour=0, minute=0, second=0, microsecond=0), day_r - timedelta(days=13) ) - day_count = (day_r - day_l) // timedelta(days=1) + 1 - days = [day_l + timedelta(days=1) * i for i in range(day_count)] import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt - fig = plt.figure(figsize=(16, 12), dpi=100) + fig = plt.figure(figsize=(8, 12), dpi=100) - ax = fig.add_subplot(211) + ax = fig.add_subplot(311) self.bar_chart(plt, ax, logs, day_l, day_r, day_count, days) - ax = fig.add_subplot(212) + ax = fig.add_subplot(312) self.tracker_chart(plt, ax, logs, day_l, day_r, day_count, days) + ax = fig.add_subplot(313) + self.average_chart(plt, ax, logs, day_l, day_r, day_count, days) + buf = io.BytesIO() fig.savefig(buf, format='png') b = buf.getvalue()