diff --git a/helpers/trendings_helper.py b/helpers/trendings_helper.py index b85caca..3e70ae3 100644 --- a/helpers/trendings_helper.py +++ b/helpers/trendings_helper.py @@ -1,6 +1,7 @@ import math, random import os import json +import copy import datetime, time import logging from collections import OrderedDict @@ -158,3 +159,48 @@ class Trendings_helper: tagSet.add(tag['name']) to_ret[self.keyTag] = list(tagSet) return to_ret + + # In contrary of getGenericTrending, it regroups items in the format: {item, start: timestamp1, end: timestamp2} + # so that it can be displayed easily on the timeline. + def getGenericTrendingOvertime(self, dateS, dateE, choice=None, topNum=0): + if choice == 'categs': + trendingType = self.keyCateg + elif choice == 'tags': + trendingType = self.keyTag + else: + trendingType = self.keyEvent + + dico_items = {} + to_format = [] + prev_days = (dateE - dateS).days + # get data + for curDate in util.getXPrevDaysSpan(dateE, prev_days): + keyname = "{}:{}".format(trendingType, util.getDateStrFormat(curDate)) + data = self.serv_redis_db.zrange(keyname, 0, topNum-1, desc=True, withscores=True) + data = [ [record[0].decode('utf8'), record[1]] for record in data ] + data = data if data is not None else [] + to_format.append([util.getTimestamp(curDate), data]) + + for timestamp, array in to_format: + for item, _ in array: + if item not in dico_items: + dico_items[item] = [] + dico_items[item].append(timestamp) + + # sort timestamps in correct order + for item in dico_items.keys(): + dico_items[item].sort() + # dico_items have the form: {item: [t1,t2,t4], ...} + to_ret = [] + ONEDAY = 60*60*24 + for item, timestamps in dico_items.items(): + obj = {'name': item, 'start': timestamps[0], 'end': timestamps[0]+ONEDAY} + for t in timestamps: + if t-obj['end'] > ONEDAY: #new entry + to_ret.append(copy.deepcopy(obj)) + obj['start'] = t + obj['end'] = t+ONEDAY + else: # contrinue entry + obj['end'] = t+ONEDAY + to_ret.append(obj) + return to_ret diff --git a/helpers/users_helper.py b/helpers/users_helper.py index 815a8e3..5dd9994 100644 --- a/helpers/users_helper.py +++ b/helpers/users_helper.py @@ -51,7 +51,7 @@ class Users_helper: keyname = "{}:{}".format(self.keyTimestamp, org) timestamps = self.serv_redis_db.zrange(keyname, 0, -1, desc=True, withscores=True) if date is None: - to_return = [ t[1] for t in timestamps ] + to_return = [ datetime.datetime.fromtimestamp(float(t[1])) for t in timestamps ] else: to_return = [] for t in timestamps: @@ -165,7 +165,7 @@ class Users_helper: data.append(to_append) except KeyError: # no data data.append([0 for x in range(24)]) - # swap: punchcard day starts on monday + # swap: punchcard day starts on sunday data = [data[6]]+data[:6] return data diff --git a/install_dependencies.sh b/install_dependencies.sh index 420fade..2059892 100755 --- a/install_dependencies.sh +++ b/install_dependencies.sh @@ -108,4 +108,9 @@ mv temp/jquery-punchcard/src/punchcard.js ./static/js mv temp/jquery-punchcard/src/punchcard.css ./static/css wget https://momentjs.com/downloads/moment.js -O ./static/js/moment.js +# timeline +VISJS_VERSION="4.21.0" +wget https://cdnjs.cloudflare.com/ajax/libs/vis/${VISJS_VERSION}/vis.min.js ./static/js/vis.min.js +wget https://cdnjs.cloudflare.com/ajax/libs/vis/${VISJS_VERSION}/vis.min.css ./static/css/vis.min.css + rm -rf ./temp diff --git a/server.py b/server.py index ed187d5..ffdd7e1 100755 --- a/server.py +++ b/server.py @@ -539,5 +539,18 @@ def getTypeaheadData(): data = trendings_helper.getTypeaheadData(dateS, dateE) return jsonify(data) +@app.route("/_getGenericTrendingOvertime") +def getGenericTrendingOvertime(): + try: + dateS = datetime.datetime.fromtimestamp(float(request.args.get('dateS'))) + dateE = datetime.datetime.fromtimestamp(float(request.args.get('dateE'))) + except: + dateS = datetime.datetime.now() - datetime.timedelta(days=7) + dateE = datetime.datetime.now() + choice = request.args.get('choice', 'events') + + data = trendings_helper.getGenericTrendingOvertime(dateS, dateE, choice) + return jsonify(data) + if __name__ == '__main__': app.run(host=server_host, port=server_port, threaded=True) diff --git a/static/js/trendings.js b/static/js/trendings.js index 79741e9..f1ce084 100644 --- a/static/js/trendings.js +++ b/static/js/trendings.js @@ -9,6 +9,7 @@ var tagPie = ["#tagPie"]; var tagLine = ["#tagLine"]; var sightingLineWidget; var discLine = ["#discussionLine"]; +var timeline; var allData; var globalColorMapping = {}; @@ -103,6 +104,14 @@ var typeaheadOption_tag = { updateLineForLabel(tagLine, tag, undefined, url_getTrendingTag); } } +var timeline_option = { + groupOrder: 'content', + maxHeight: '94vh', + verticalScroll: true, + horizontalScroll: true, + zoomKey: 'ctrlKey', +}; + /* FUNCTIONS */ function getColor(label) { @@ -134,7 +143,18 @@ function getTextColour(rgb) { return 'black'; } } -function legendFormatter(label, series) { + +// If json (from tag), only retreive the name> otherwise return the supplied arg. +function getOnlyName(potentialJson) { + try { + jsonLabel = JSON.parse(potentialJson); + return jsonLabel.name; + } catch(err) { + return potentialJson; + } +} + +function legendFormatter(label) { try { jsonLabel = JSON.parse(label); var backgroundColor = jsonLabel.colour; @@ -156,7 +176,7 @@ function legendFormatter(label, series) { } return '