Skip to content

Commit

Permalink
graph visualization of econoimc activity as first class part of the app
Browse files Browse the repository at this point in the history
  • Loading branch information
owocki committed Feb 8, 2020
1 parent 03f899c commit d7f6bc2
Show file tree
Hide file tree
Showing 6 changed files with 516 additions and 70 deletions.
1 change: 1 addition & 0 deletions app/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@
re_path(r'^_administration/cohort/$', dataviz.views.cohort, name='cohort'),
re_path(r'^_administration/funnel/$', dataviz.views.funnel, name='funnel'),
re_path(r'^_administration/viz/?$', dataviz.d3_views.viz_index, name='viz_index'),
re_path(r'^_administration/mesh/?$', dataviz.d3_views.mesh_network_viz, name='mesh_network_viz'),
re_path(r'^_administration/viz/sunburst/(.*)?$', dataviz.d3_views.viz_sunburst, name='viz_sunburst'),
re_path(r'^_administration/viz/chord/(.*)?$', dataviz.d3_views.viz_chord, name='viz_chord'),
re_path(r'^_administration/viz/steamgraph/(.*)?$', dataviz.d3_views.viz_steamgraph, name='viz_steamgraph'),
Expand Down
3 changes: 3 additions & 0 deletions app/assets/v2/js/admin/graph.min.js

Large diffs are not rendered by default.

94 changes: 94 additions & 0 deletions app/dataviz/d3_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
import json
import math
import random
import re
import time

from django.contrib.admin.views.decorators import staff_member_required
from django.http import HttpResponse, JsonResponse
from django.template.response import TemplateResponse
from django.utils import timezone

import pytz
from dashboard.models import Bounty, BountyFulfillment, Profile, Tip
from marketing.models import Stat
from perftools.models import JSONStore
Expand Down Expand Up @@ -714,6 +716,98 @@ def viz_scatterplot_data_helper(keyword, hide_usernames=False):
return output


def is_an_edge(handle, edges):
for edge in edges:
if handle == edge[0]:
return True
if handle == edge[1]:
return True
return False


def normalize_handle(handle):
return re.sub(r'\W+', '', handle)


@staff_member_required
def mesh_network_viz(request, ):
"""Render a Mesh Network visualization
Args:
key (str): The key type to visualize.
Returns:
TemplateResponse: The populated mesh data visualization template.
"""
handles = []
edges = []
year = int(request.GET.get('year', timezone.now().strftime("%Y")))
month = int(request.GET.get('month', timezone.now().strftime("%m")))
day = int(request.GET.get('day', 1))
start_date = timezone.datetime(year, month, day, 1, tzinfo=pytz.UTC)
_type = request.GET.get('type', 'all')

since = f"{year}/{month}/{day}"

from dashboard.models import Earning
earnings = Earning.objects.filter(created_on__gt=start_date)
if _type != 'all':
from django.contrib.contenttypes.models import ContentType
mapping = {
'grant': ContentType.objects.get(app_label='grants', model='contribution'),
'kudos': ContentType.objects.get(app_label='kudos', model='kudostransfer'),
'tip': ContentType.objects.get(app_label='dashboard', model='tip'),
'bounty': ContentType.objects.get(app_label='dashboard', model='bountyfulfillment'),
}
earnings = earnings.filter(source_type=mapping[_type])
earnings = earnings.values_list('from_profile__handle', 'to_profile__handle')
for obj in earnings:
handle1 = obj[0]
handle2 = obj[1]
handles.append(handle1)
handles.append(handle2)
edges.append([handle1, handle2])

# assemble and output
handles = set(handles)
handles = [handle for handle in handles if is_an_edge(handle, edges)]
graph = ""
print(len(handles))
counter = 1
for handle in handles:
if handle:
handle = normalize_handle(handle)
counter += 1
graph += (
f'var user_{handle} = new GRAPHVIS.Node({counter}); user_{handle}.data.title = "user_{handle}"; graph.addNode(user_{handle}); drawNode(user_{handle});'
)

for edge in edges:
handle1 = edge[0]
handle2 = edge[1]
if handle1 and handle2:
handle1 = normalize_handle(handle1)
handle2 = normalize_handle(handle2)
if handle1 and handle2:
graph += (f"graph.addEdge(user_{handle1}, user_{handle2}); drawEdge(user_{handle1}, user_{handle2}); ")

params = {
"type": _type,
"graph": graph,
"since": since,
"year": year,
"month": month,
"day": day,
"years": range(2017, 1 + int(timezone.now().strftime("%Y"))),
"months": range(1, 12),
"days": range(1, 31),
'types': ['all', 'grant', 'bounty', 'tip', 'kudos']
}
response = TemplateResponse(request, 'dataviz/mesh.html', params)
return response


def viz_scatterplot_helper(request, key='hourly_rate', template='dataviz/scatterplot.html', hide_usernames=False):
"""Render a scatterplot visualization.
Expand Down
Loading

0 comments on commit d7f6bc2

Please sign in to comment.