Skip to content
Snippets Groups Projects
Commit 7a458e70 authored by Benjamin Hättasch's avatar Benjamin Hättasch
Browse files

Introduce color coding for recently changed akslots in plan

Add new helper property to model
Add and use template tag for color coding
Add helpfer functions for color blending (gradient and simple)
Also show timestamp of last edit in admin view
Introduce setting to control which changes will be higlighted
parent 68b2ef20
Branches
No related tags found
No related merge requests found
......@@ -74,6 +74,8 @@ admin.site.register(Room)
@admin.register(AKSlot)
class AKSlotAdmin(admin.ModelAdmin):
readonly_fields = ['updated']
def get_form(self, request, obj=None, change=False, **kwargs):
# Use timezone of associated event
if obj is not None and obj.event.timezone:
......
# Create your models here.
import datetime
import itertools
from django.db import models
from django.utils import timezone
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
from timezone_field import TimeZoneField
......@@ -301,3 +301,12 @@ class AKSlot(models.Model):
Retrieve end time of the AK slot
"""
return self.start + datetime.timedelta(hours=float(self.duration))
@property
def seconds_since_last_update(self):
"""
Return minutes since last update
:return: minutes since last update
:rtype: float
"""
return (timezone.now() - self.updated).total_seconds()
{% load tz %}
{% load tags_AKPlan %}
[
{% for slot in slots %}
......@@ -8,8 +9,8 @@
'start': '{{ slot.start | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
'end': '{{ slot.end | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
'resourceId': '{{ slot.room.title }}',
'backgroundColor': '{{ slot.ak.category.color }}',
'borderColor': '{{ slot.ak.track.color }}',
'backgroundColor': '{{ slot|highlight_change_colors }}',
'borderColor': '{{ slot.ak.category.color }}',
'url': '{% url 'submit:ak_detail' event_slug=event.slug pk=slot.ak.pk %}'
},
{% endif %}
......
# gradients based on http://bsou.io/posts/color-gradients-with-python
def hex_to_rgb(hex):
"""
Convert hex color to RGB color code
:param hex: hex encoded color
:type hex: str
:return: rgb encoded version of given color
:rtype: list[int]
"""
# Pass 16 to the integer function for change of base
return [int(hex[i:i+2], 16) for i in range(1,6,2)]
def rgb_to_hex(rgb):
"""
Convert rgb color (list) to hex encoding (str)
:param rgb: rgb encoded color
:type rgb: list[int]
:return: hex encoded version of given color
:rtype: str
"""
# Components need to be integers for hex to make sense
rgb = [int(x) for x in rgb]
return "#"+"".join(["0{0:x}".format(v) if v < 16 else
"{0:x}".format(v) for v in rgb])
def linear_blend(start_hex, end_hex, position):
"""
Create a linear blend between two colors and return color code on given position of the range from 0 to 1
:param start_hex: hex representation of start color
:type start_hex: str
:param end_hex: hex representation of end color
:type end_hex: str
:param position: position in range from 0 to 1
:type position: float
:return: hex encoded interpolated color
:rtype: str
"""
s = hex_to_rgb(start_hex)
f = hex_to_rgb(end_hex)
blended = [int(s[j] + position * (f[j] - s[j])) for j in range(3)]
return rgb_to_hex(blended)
def darken(start_hex, amount):
"""
Darken the given color by the given amount (sensitivity will be cut in half)
:param start_hex: original color
:type start_hex: str
:param amount: how much to darken (1.0 -> 50% darker)
:type amount: float
:return: darker version of color
:rtype: str
"""
start_rbg = hex_to_rgb(start_hex)
darker = [int(s * (1 - amount * .5)) for s in start_rbg]
return rgb_to_hex(darker)
from django import template
from AKPlan.templatetags.color_gradients import darken
from AKPlanning import settings
register = template.Library()
@register.filter
def highlight_change_colors(akslot):
seconds_since_update = akslot.seconds_since_last_update
# Last change long ago? Use default color
if seconds_since_update > settings.PLAN_MAX_HIGHLIGHT_UPDATE_SECONDS:
return akslot.ak.category.color
# Recent change? Calculate gradient blend between red and
recentness = seconds_since_update / settings.PLAN_MAX_HIGHLIGHT_UPDATE_SECONDS
return darken("#b71540", recentness)
# return linear_blend("#b71540", "#000000", recentness)
......@@ -164,5 +164,7 @@ PLAN_WALL_HOURS_RETROSPECT = 3
PLAN_WALL_HOURS_FUTURE = 18
# Should the plan use a hierarchy of buildings and rooms?
PLAN_SHOW_HIERARCHY = True
# For which time (in seconds) should changes of akslots be highlighted in plan?
PLAN_MAX_HIGHLIGHT_UPDATE_SECONDS = 2 * 60 * 60
include(optional("settings/*.py"))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment