2021-02-21 19:13:22 +00:00
|
|
|
import holoviews as hv
|
|
|
|
import pandas as pd
|
|
|
|
|
|
|
|
from django.utils import timezone
|
|
|
|
|
2021-03-01 17:05:14 +00:00
|
|
|
from math import pi
|
|
|
|
|
2021-02-21 19:13:22 +00:00
|
|
|
from bokeh.models import HoverTool
|
2021-03-01 17:05:14 +00:00
|
|
|
from bokeh.plotting import figure
|
|
|
|
from bokeh.transform import cumsum
|
2024-05-17 13:03:20 +00:00
|
|
|
from bokeh.layouts import column
|
2021-02-22 06:51:27 +00:00
|
|
|
from holoviews.operation import timeseries
|
2021-02-21 19:13:22 +00:00
|
|
|
from dateutil.relativedelta import relativedelta
|
|
|
|
|
2021-03-03 07:39:26 +00:00
|
|
|
from .models import Status, Mood, StatusActivity
|
2021-02-21 19:13:22 +00:00
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
|
2021-02-26 06:38:17 +00:00
|
|
|
def moodstats(user):
|
2024-03-24 15:28:10 +00:00
|
|
|
hv.extension("bokeh")
|
2021-02-21 19:13:22 +00:00
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
tooltips = [("Date", "@date{%F %H:%M}"), ("Mood", "@name (@value)")]
|
2021-02-21 19:13:22 +00:00
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
formatters = {"@date": "datetime"}
|
2021-02-21 19:13:22 +00:00
|
|
|
|
|
|
|
hover = HoverTool(tooltips=tooltips, formatters=formatters)
|
|
|
|
|
2021-03-01 17:05:14 +00:00
|
|
|
pointdict = {"date": [], "value": [], "color": [], "name": []}
|
2021-02-21 19:13:22 +00:00
|
|
|
|
2021-02-22 06:51:27 +00:00
|
|
|
for status in Status.objects.filter(user=user):
|
2021-02-21 19:13:22 +00:00
|
|
|
if status.mood:
|
|
|
|
pointdict["date"].append(status.timestamp)
|
|
|
|
pointdict["value"].append(status.mood.value)
|
|
|
|
pointdict["color"].append(status.mood.color)
|
2021-03-01 17:05:14 +00:00
|
|
|
pointdict["name"].append(status.mood.name)
|
2021-02-21 19:13:22 +00:00
|
|
|
|
|
|
|
pointframe = pd.DataFrame.from_dict(pointdict)
|
|
|
|
|
|
|
|
points = hv.Points(pointframe)
|
|
|
|
|
|
|
|
points.opts(
|
2024-03-24 15:28:10 +00:00
|
|
|
tools=[hover],
|
|
|
|
color="color",
|
|
|
|
cmap="Category20",
|
|
|
|
line_color="black",
|
|
|
|
size=25,
|
|
|
|
width=600,
|
|
|
|
height=400,
|
|
|
|
show_grid=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
pointtuples = [
|
|
|
|
(pointdict["date"][i], pointdict["value"][i])
|
|
|
|
for i in range(len(pointdict["date"]))
|
|
|
|
]
|
2021-02-21 19:13:22 +00:00
|
|
|
|
|
|
|
line = hv.Curve(pointtuples)
|
|
|
|
|
2021-02-22 06:51:27 +00:00
|
|
|
maxval = Mood.objects.filter(user=user).latest("value").value
|
2021-02-22 06:59:51 +00:00
|
|
|
maxy = maxval + max(maxval * 0.1, 1)
|
2021-02-22 06:51:27 +00:00
|
|
|
|
2021-02-28 18:58:38 +00:00
|
|
|
maxx = timezone.now().timestamp() * 1000
|
2024-03-24 15:28:10 +00:00
|
|
|
minx = maxx - (60 * 60 * 24 * 7) * 1000
|
2021-02-21 20:03:34 +00:00
|
|
|
|
2021-02-22 06:51:27 +00:00
|
|
|
output = points * line * timeseries.rolling(line, rolling_window=7)
|
|
|
|
output.opts(ylim=(0, maxy), xlim=(minx, maxx))
|
2021-02-21 19:59:39 +00:00
|
|
|
|
|
|
|
return output
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
|
2021-02-26 06:26:52 +00:00
|
|
|
def activitystats(user):
|
2021-02-21 19:59:39 +00:00
|
|
|
output = {}
|
|
|
|
|
2021-02-25 14:33:28 +00:00
|
|
|
for status in Status.objects.filter(user=user):
|
2021-02-21 19:59:39 +00:00
|
|
|
for activity in status.activity_set:
|
2021-02-25 14:33:28 +00:00
|
|
|
if not activity in output.keys():
|
|
|
|
output[activity] = {
|
|
|
|
"alltime": 0,
|
|
|
|
"yearly": 0,
|
|
|
|
"monthly": 0,
|
2024-03-24 15:28:10 +00:00
|
|
|
"weekly": 0,
|
2021-02-25 14:33:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
output[activity]["alltime"] += 1
|
|
|
|
|
|
|
|
if status.timestamp > timezone.now() - relativedelta(years=1):
|
|
|
|
output[activity]["yearly"] += 1
|
|
|
|
|
|
|
|
if status.timestamp > timezone.now() - relativedelta(months=1):
|
|
|
|
output[activity]["monthly"] += 1
|
|
|
|
|
|
|
|
if status.timestamp > timezone.now() - relativedelta(weeks=1):
|
|
|
|
output[activity]["weekly"] += 1
|
2021-02-21 19:13:22 +00:00
|
|
|
|
2021-03-01 17:05:14 +00:00
|
|
|
return output
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
|
2021-03-01 17:05:14 +00:00
|
|
|
def moodpies(user):
|
2024-03-24 15:28:10 +00:00
|
|
|
hv.extension("bokeh")
|
2021-03-01 17:05:14 +00:00
|
|
|
|
|
|
|
maxdate = timezone.now()
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
weekly_moods = Status.objects.filter(
|
|
|
|
user=user,
|
|
|
|
timestamp__lte=maxdate,
|
|
|
|
timestamp__gte=maxdate - relativedelta(weeks=1),
|
|
|
|
)
|
|
|
|
monthly_moods = Status.objects.filter(
|
|
|
|
user=user,
|
|
|
|
timestamp__lte=maxdate,
|
|
|
|
timestamp__gte=maxdate - relativedelta(months=1),
|
|
|
|
)
|
|
|
|
yearly_moods = Status.objects.filter(
|
|
|
|
user=user,
|
|
|
|
timestamp__lte=maxdate,
|
|
|
|
timestamp__gte=maxdate - relativedelta(years=1),
|
|
|
|
)
|
2021-03-01 17:05:14 +00:00
|
|
|
|
|
|
|
weekly = dict()
|
|
|
|
colors = []
|
|
|
|
|
|
|
|
for mood in Mood.objects.filter(user=user):
|
|
|
|
weekly[mood.name] = 0
|
|
|
|
colors.append(mood.color)
|
|
|
|
|
|
|
|
monthly, yearly = weekly.copy(), weekly.copy()
|
|
|
|
|
|
|
|
for status in weekly_moods:
|
|
|
|
if status.mood:
|
|
|
|
weekly[status.mood.name] += 1
|
|
|
|
|
|
|
|
for status in monthly_moods:
|
|
|
|
if status.mood:
|
|
|
|
monthly[status.mood.name] += 1
|
|
|
|
|
|
|
|
for status in yearly_moods:
|
|
|
|
if status.mood:
|
|
|
|
yearly[status.mood.name] += 1
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
weekly_data = (
|
|
|
|
pd.Series(weekly).reset_index(name="value").rename(columns={"index": "mood"})
|
|
|
|
)
|
|
|
|
weekly_data["angle"] = weekly_data["value"] / weekly_data["value"].sum() * 2 * pi
|
|
|
|
weekly_data["color"] = colors
|
|
|
|
|
|
|
|
weekly_chart = figure(
|
|
|
|
height=350,
|
|
|
|
title="Weekly",
|
|
|
|
toolbar_location=None,
|
|
|
|
tools="hover",
|
|
|
|
tooltips="@mood: @value",
|
|
|
|
)
|
2021-03-01 17:05:14 +00:00
|
|
|
weekly_chart.axis.visible = False
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
weekly_chart.wedge(
|
|
|
|
x=0,
|
|
|
|
y=1,
|
|
|
|
radius=0.4,
|
|
|
|
start_angle=cumsum("angle", include_zero=True),
|
|
|
|
end_angle=cumsum("angle"),
|
|
|
|
line_color="white",
|
|
|
|
fill_color="color",
|
2024-03-24 15:29:27 +00:00
|
|
|
legend_label="mood",
|
2024-03-24 15:28:10 +00:00
|
|
|
source=weekly_data,
|
|
|
|
)
|
|
|
|
|
|
|
|
monthly_data = (
|
|
|
|
pd.Series(monthly).reset_index(name="value").rename(columns={"index": "mood"})
|
|
|
|
)
|
|
|
|
monthly_data["angle"] = monthly_data["value"] / monthly_data["value"].sum() * 2 * pi
|
|
|
|
monthly_data["color"] = colors
|
|
|
|
|
|
|
|
monthly_chart = figure(
|
|
|
|
height=350,
|
|
|
|
title="Monthly",
|
|
|
|
toolbar_location=None,
|
|
|
|
tools="hover",
|
|
|
|
tooltips="@mood: @value",
|
|
|
|
)
|
2021-03-03 07:39:26 +00:00
|
|
|
monthly_chart.axis.visible = False
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
monthly_chart.wedge(
|
|
|
|
x=0,
|
|
|
|
y=1,
|
|
|
|
radius=0.4,
|
|
|
|
start_angle=cumsum("angle", include_zero=True),
|
|
|
|
end_angle=cumsum("angle"),
|
|
|
|
line_color="white",
|
|
|
|
fill_color="color",
|
|
|
|
legend_label="mood",
|
|
|
|
source=monthly_data,
|
|
|
|
)
|
|
|
|
|
|
|
|
yearly_data = (
|
|
|
|
pd.Series(yearly).reset_index(name="value").rename(columns={"index": "mood"})
|
|
|
|
)
|
|
|
|
yearly_data["angle"] = yearly_data["value"] / yearly_data["value"].sum() * 2 * pi
|
|
|
|
yearly_data["color"] = colors
|
|
|
|
|
|
|
|
yearly_chart = figure(
|
|
|
|
height=350,
|
|
|
|
title="Yearly",
|
|
|
|
toolbar_location=None,
|
|
|
|
tools="hover",
|
|
|
|
tooltips="@mood: @value",
|
|
|
|
)
|
2021-03-03 07:39:26 +00:00
|
|
|
yearly_chart.axis.visible = False
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
yearly_chart.wedge(
|
|
|
|
x=0,
|
|
|
|
y=1,
|
|
|
|
radius=0.4,
|
|
|
|
start_angle=cumsum("angle", include_zero=True),
|
|
|
|
end_angle=cumsum("angle"),
|
|
|
|
line_color="white",
|
|
|
|
fill_color="color",
|
|
|
|
legend_label="mood",
|
|
|
|
source=yearly_data,
|
|
|
|
)
|
2021-03-03 07:39:26 +00:00
|
|
|
|
|
|
|
return column(weekly_chart, monthly_chart, yearly_chart)
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
|
2021-03-03 07:39:26 +00:00
|
|
|
def activitymood(activity):
|
2024-03-24 15:28:10 +00:00
|
|
|
hv.extension("bokeh")
|
2021-03-03 07:39:26 +00:00
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
tooltips = [("Date", "@date{%F %H:%M}"), ("Mood", "@name (@value)")]
|
2021-03-03 07:39:26 +00:00
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
formatters = {"@date": "datetime"}
|
2021-03-03 07:39:26 +00:00
|
|
|
|
|
|
|
hover = HoverTool(tooltips=tooltips, formatters=formatters)
|
|
|
|
|
|
|
|
pointdict = {"date": [], "value": [], "color": [], "name": []}
|
|
|
|
|
|
|
|
for statusactivity in StatusActivity.objects.filter(activity=activity):
|
|
|
|
if statusactivity.status.mood:
|
|
|
|
pointdict["date"].append(statusactivity.status.timestamp)
|
|
|
|
pointdict["value"].append(statusactivity.status.mood.value)
|
|
|
|
pointdict["color"].append(statusactivity.status.mood.color)
|
|
|
|
pointdict["name"].append(statusactivity.status.mood.name)
|
|
|
|
|
|
|
|
pointframe = pd.DataFrame.from_dict(pointdict)
|
|
|
|
|
|
|
|
points = hv.Points(pointframe)
|
|
|
|
|
|
|
|
points.opts(
|
2024-03-24 15:28:10 +00:00
|
|
|
tools=[hover],
|
|
|
|
color="color",
|
|
|
|
cmap="Category20",
|
|
|
|
line_color="black",
|
|
|
|
size=25,
|
|
|
|
width=600,
|
|
|
|
height=400,
|
|
|
|
show_grid=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
pointtuples = [
|
|
|
|
(pointdict["date"][i], pointdict["value"][i])
|
|
|
|
for i in range(len(pointdict["date"]))
|
|
|
|
]
|
2021-03-03 07:39:26 +00:00
|
|
|
|
|
|
|
line = hv.Curve(pointtuples)
|
|
|
|
|
|
|
|
maxval = Mood.objects.filter(user=activity.user).latest("value").value
|
|
|
|
maxy = maxval + max(maxval * 0.1, 1)
|
|
|
|
|
|
|
|
maxx = timezone.now().timestamp() * 1000
|
2024-03-24 15:28:10 +00:00
|
|
|
minx = maxx - (60 * 60 * 24 * 7) * 1000
|
2021-03-03 07:39:26 +00:00
|
|
|
|
|
|
|
output = points * line * timeseries.rolling(line, rolling_window=7)
|
|
|
|
output.opts(ylim=(0, maxy), xlim=(minx, maxx))
|
|
|
|
|
|
|
|
return output
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
|
2021-03-03 07:39:26 +00:00
|
|
|
def activitypies(activity):
|
2024-03-24 15:28:10 +00:00
|
|
|
hv.extension("bokeh")
|
2021-03-03 07:39:26 +00:00
|
|
|
|
|
|
|
maxdate = timezone.now()
|
|
|
|
|
|
|
|
sa = StatusActivity.objects.filter(activity=activity)
|
|
|
|
|
|
|
|
weekly = dict()
|
|
|
|
colors = []
|
|
|
|
|
|
|
|
for mood in Mood.objects.filter(user=activity.user):
|
|
|
|
weekly[mood.name] = 0
|
|
|
|
colors.append(mood.color)
|
|
|
|
|
|
|
|
monthly, yearly = weekly.copy(), weekly.copy()
|
|
|
|
|
|
|
|
for single in sa:
|
|
|
|
if single.status.mood:
|
|
|
|
if single.status.timestamp > timezone.now() - relativedelta(weeks=1):
|
|
|
|
weekly[single.status.mood.name] += 1
|
|
|
|
if single.status.timestamp > timezone.now() - relativedelta(months=1):
|
|
|
|
monthly[single.status.mood.name] += 1
|
|
|
|
if single.status.timestamp > timezone.now() - relativedelta(years=1):
|
|
|
|
yearly[single.status.mood.name] += 1
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
weekly_data = (
|
|
|
|
pd.Series(weekly).reset_index(name="value").rename(columns={"index": "mood"})
|
|
|
|
)
|
|
|
|
weekly_data["angle"] = weekly_data["value"] / weekly_data["value"].sum() * 2 * pi
|
|
|
|
weekly_data["color"] = colors
|
|
|
|
|
|
|
|
weekly_chart = figure(
|
|
|
|
height=350,
|
|
|
|
title="Weekly",
|
|
|
|
toolbar_location=None,
|
|
|
|
tools="hover",
|
|
|
|
tooltips="@mood: @value",
|
|
|
|
)
|
2021-03-03 07:39:26 +00:00
|
|
|
weekly_chart.axis.visible = False
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
weekly_chart.wedge(
|
|
|
|
x=0,
|
|
|
|
y=1,
|
|
|
|
radius=0.4,
|
|
|
|
start_angle=cumsum("angle", include_zero=True),
|
|
|
|
end_angle=cumsum("angle"),
|
|
|
|
line_color="white",
|
|
|
|
fill_color="color",
|
|
|
|
legend_label="mood",
|
|
|
|
source=weekly_data,
|
|
|
|
)
|
|
|
|
|
|
|
|
monthly_data = (
|
|
|
|
pd.Series(monthly).reset_index(name="value").rename(columns={"index": "mood"})
|
|
|
|
)
|
|
|
|
monthly_data["angle"] = monthly_data["value"] / monthly_data["value"].sum() * 2 * pi
|
|
|
|
monthly_data["color"] = colors
|
|
|
|
|
|
|
|
monthly_chart = figure(
|
|
|
|
height=350,
|
|
|
|
title="Monthly",
|
|
|
|
toolbar_location=None,
|
|
|
|
tools="hover",
|
|
|
|
tooltips="@mood: @value",
|
|
|
|
)
|
2021-03-01 17:05:14 +00:00
|
|
|
monthly_chart.axis.visible = False
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
monthly_chart.wedge(
|
|
|
|
x=0,
|
|
|
|
y=1,
|
|
|
|
radius=0.4,
|
|
|
|
start_angle=cumsum("angle", include_zero=True),
|
|
|
|
end_angle=cumsum("angle"),
|
|
|
|
line_color="white",
|
|
|
|
fill_color="color",
|
|
|
|
legend_label="mood",
|
|
|
|
source=monthly_data,
|
|
|
|
)
|
|
|
|
|
|
|
|
yearly_data = (
|
|
|
|
pd.Series(yearly).reset_index(name="value").rename(columns={"index": "mood"})
|
|
|
|
)
|
|
|
|
yearly_data["angle"] = yearly_data["value"] / yearly_data["value"].sum() * 2 * pi
|
|
|
|
yearly_data["color"] = colors
|
|
|
|
|
|
|
|
yearly_chart = figure(
|
|
|
|
height=350,
|
|
|
|
title="Yearly",
|
|
|
|
toolbar_location=None,
|
|
|
|
tools="hover",
|
|
|
|
tooltips="@mood: @value",
|
|
|
|
)
|
2021-03-01 17:05:14 +00:00
|
|
|
yearly_chart.axis.visible = False
|
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
yearly_chart.wedge(
|
|
|
|
x=0,
|
|
|
|
y=1,
|
|
|
|
radius=0.4,
|
|
|
|
start_angle=cumsum("angle", include_zero=True),
|
|
|
|
end_angle=cumsum("angle"),
|
|
|
|
line_color="white",
|
|
|
|
fill_color="color",
|
|
|
|
legend_label="mood",
|
|
|
|
source=yearly_data,
|
|
|
|
)
|
2021-03-01 17:05:14 +00:00
|
|
|
|
2024-03-24 15:28:10 +00:00
|
|
|
return column(weekly_chart, monthly_chart, yearly_chart)
|