Skip to content

Commit c44781a

Browse files
authored
Merge pull request #52 from dgets/develop
Develop; interval graphing now working (not polished).
2 parents b18b60e + 7691aff commit c44781a

File tree

5 files changed

+109
-12
lines changed

5 files changed

+109
-12
lines changed

dataview/static/dataview/graphing_internals.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,15 @@ getJSON = function(url, callback) {
1616
};
1717

1818
xhr.send();
19-
};
19+
};
20+
21+
function secondsToHms(d) {
22+
d = Number(d);
23+
24+
var h = Math.floor(d / 3600);
25+
var m = Math.floor(d % 3600 / 60);
26+
var s = Math.floor(d % 3600 % 60);
27+
28+
return ('0' + h).slice(-2) + ":" + ('0' + m).slice(-2) + ":" + ('0' + s).slice(-2);
29+
}
30+

dataview/templates/dataview/data_summary.html

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@
77
<link rel="stylesheet" type="text/css"
88
href="{% static 'recadm/lasttime.css' %}">
99

10-
<!-- unnecessary in this version
1110
<script>
1211
var getJSON;
1312
</script>
1413
<script src="{% static 'dataview/graphing_internals.js' %}"></script>
15-
-->
1614

1715
</head>
1816
<body>
@@ -127,6 +125,37 @@ <h4>Time Between Subsequent Administrations</h4>
127125
{% endfor %}
128126
</ol>
129127

128+
<div class="interval_chart"></div>
129+
<script src="//d3js.org/d3.v3.min.js"></script>
130+
<script>
131+
let json_src2 = '{% url 'dataview:dump_interval_graph_data' sub_id %}';
132+
133+
fetch(json_src2)
134+
.then(res => res.json())
135+
.then((out) => {
136+
//debugging schitt
137+
//out = [ 7, 15, 2, 12, 13 ];
138+
console.log(out);
139+
140+
//var data = [];
141+
//for (var ouah in out) {
142+
// data.push(out[ouah]);
143+
//}
144+
145+
var x = d3.scale.linear()
146+
.domain([0, d3.max(out.timespans)])
147+
.range([0, d3.max(out.timespans)]);
148+
149+
d3.select(".interval_chart")
150+
.selectAll("div")
151+
.data(out.timespans)
152+
.enter().append("div")
153+
.style("width", function(d) { return x(d) + "px"; })
154+
.text(function(d) { return (secondsToHms(d / out.scale_factor)); });
155+
})
156+
.catch(err => { throw err });
157+
</script>
158+
130159
{% else %}
131160

132161
<p>No timespans have been recorded.</p>

dataview/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77
path('', views.IndexView.as_view(), name='index'),
88
path('<int:pk>/', views.SubAdminDataView.as_view(), name='data_summary'),
99
path('dump_dose_graph_data/<int:sub_id>/', views.dump_dose_graph_data, name='dump_dose_graph_data'),
10+
path('dump_interval_graph_data/<int:sub_id>/', views.dump_interval_graph_data, name='dump_interval_graph_data'),
1011
]

dataview/views.py

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,16 @@ def get_context_data(self, **kwargs):
9999

100100
total_span += span
101101

102+
# errors here if there are 0 or 1 usages, obviously
102103
average_span = round_timedelta_to_15min_floor(total_span / (usage_count - 1))
104+
scale_factor = get_graph_normalization_divisor(longest_span.total_seconds(), 600)
103105

104106
return add_header_info({'usages': usages, 'usage_count': usage_count, 'usage_average': usage_average,
105107
'usage_high': highest_administered, 'usage_low': lowest_administered,
106108
'usage_total': total_administered,
107109
'sub_name': Substance.objects.filter(pk=self.kwargs['pk'])[0].common_name,
108110
'sub_id': self.kwargs['pk'], 'longest_span': longest_span,
109-
'shortest_span': shortest_span, 'timespans': timespans,
111+
'shortest_span': shortest_span, 'timespans': timespans, 'scale_factor': scale_factor,
110112
'average_span': average_span})
111113

112114

@@ -126,22 +128,49 @@ def dump_dose_graph_data(request, sub_id):
126128
:return:
127129
"""
128130

129-
usage_graph_data = {}
130-
# usage_sub_id = request.POST['sub']
131-
usages = Usage.objects.filter(sub=sub_id)[:20] # pk or usage_sub_id?
131+
dosage_graph_data = []
132+
# dosage_sub_id = request.POST['sub']
133+
usages = Usage.objects.filter(sub=sub_id)[:20]
132134

133-
cntr = 0
135+
# cntr = 0
134136
for use in usages:
135-
# usage_graph_data[str(use.timestamp)] = float(use.dosage)
137+
# dosage_graph_data[str(use.timestamp)] = float(use.dosage)
136138
# NOTE: switching to a standard array for now for simplicity in the
137139
# template's javascript; we can add more gravy later
138140

139141
# later on we can look at using use.notes as hover-over text for each
140142
# graph bar, or something of the like
141-
usage_graph_data[cntr] = float(use.dosage)
142-
cntr += 1
143+
dosage_graph_data.append(float(use.dosage))
144+
# cntr += 1
143145

144-
return HttpResponse(json.dumps(usage_graph_data), content_type='application/json')
146+
return HttpResponse(json.dumps(dosage_graph_data), content_type='application/json')
147+
148+
149+
def dump_interval_graph_data(request, sub_id):
150+
# interval_graph_data = {}
151+
usages = Usage.objects.filter(sub=sub_id)[:20]
152+
153+
timespans = []
154+
prev_time = None # would we (perhaps optionally) want timezone.now()?
155+
max_span = datetime.timedelta(0)
156+
for use in usages:
157+
if prev_time is not None:
158+
current_delta = datetime.timedelta
159+
current_delta = use.timestamp - prev_time
160+
current_delta = round_timedelta_to_15min_floor(current_delta)
161+
timespans.append(current_delta.total_seconds())
162+
163+
if current_delta > max_span:
164+
max_span = current_delta
165+
166+
prev_time = use.timestamp
167+
168+
scale_factor = get_graph_normalization_divisor(max_span.total_seconds(), 300)
169+
for cntr in range(0, len(timespans)):
170+
timespans[cntr] = timespans[cntr] * scale_factor
171+
172+
return HttpResponse(json.dumps({ 'scale_factor': scale_factor, 'timespans': timespans }),
173+
content_type='application/json')
145174

146175

147176
def add_header_info(page_data):
@@ -173,3 +202,21 @@ def round_timedelta_to_15min_floor(span):
173202
dingleberry = span.total_seconds() % fifteen_min.seconds
174203

175204
return span - datetime.timedelta(seconds=dingleberry)
205+
206+
207+
def get_graph_normalization_divisor(max_qty, graph_max_boundary):
208+
"""
209+
Method takes the maximum quantity (dimensionless), along with the maximum
210+
dimension on the quantity axis, and returns the scale to divide by in
211+
order to make things fit properly in the graph.
212+
213+
:param max_qty:
214+
:param graph_max_boundary:
215+
:return:
216+
"""
217+
218+
scale_factor = 1
219+
if max_qty <= (graph_max_boundary / 2) or max_qty > graph_max_boundary:
220+
scale_factor = graph_max_boundary / max_qty
221+
222+
return scale_factor

recadm/static/recadm/lasttime.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,15 @@ p {
115115
color: white;
116116
}
117117

118+
.interval_chart div {
119+
font: 10px sans-serif;
120+
background-color: steelblue;
121+
text-align: right;
122+
padding: 3px;
123+
margin: 1px;
124+
color: white;
125+
}
126+
118127
.axis {
119128
font: 10px sans-serif;
120129
}

0 commit comments

Comments
 (0)