Skip to content

Instantly share code, notes, and snippets.

Created July 11, 2016 11:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/98b8a8cd875b3d50f4d77b93c14b322e to your computer and use it in GitHub Desktop.
Save anonymous/98b8a8cd875b3d50f4d77b93c14b322e to your computer and use it in GitHub Desktop.
Glucose - nested v5 - comments
/*
MIT License 2016 - Dealga McArdle.
=================================
For now this is moderately light usage of d3.js - maybe to the chagrin of more weathered
d3.js masters - simply to illustrate a problem i'm facing.
typical json to parse:
....
"YYYY/MM/DD": {
"sleeptimes": "00:00->07:00,15:20->18:30,23:00->24:00",
"comments": "AMC visit, Cystoscopy - all clear",
"glucose": [
{"time": "06:35", "value": 6.94},
{"time": "15:18", "value": 14.93},
{"time": "20:28", "value": 11.77},
{"time": "22:13", "value": 12.71}
]
},
....
- could color grade using 0-5 5-10 10-15 15-20 20-25 25-up
intentionally left blank.
*/
function get_ratio_from_time(time_str){
// this function converts a time_str into how far into the day it is
// f.ex 12:00 => 0.5 06:00 => 0.25
var time_parts = time_str.split(':');
var a = +time_parts[0];
var b = +time_parts[1];
return (1/1440*((a*60) + b))
}
function get_color(tval){
if (tval < 5.0){return {bg:"#18dff5", tx: "#111"}}
else if (tval >= 5.0 && tval < 10.0){return {bg:"#27f518", tx: "#111"}}
else if (tval >= 10.0 && tval < 15.0){return {bg:"#c8f97f", tx: "#111"}}
else if (tval >= 15.0 && tval < 20.0){return {bg:"#ffb76b", tx: "#111"}}
else if (tval >= 20.0){return {bg:"#fe70bc", tx: "#ffffff"}}
}
var svg = d3.select("svg")
var format_day = d3.time.format("%Y/%m/%d");
var format_hours = d3.time.format("%H:%M");
var formatTime = d3.time.format("%m / %d");
d3.json("times.json", function(error, times) {
if (error) throw error;
times = json_preprocessor(times);
draw_graph(times);
});
function times_preprocessor(t){
if (!t){return []}
var ts = t.split(',');
var emb = [];
for (var k of ts){
var abl = k.split('->');
if (abl.length === 2){ emb.push(abl); }
}
return emb;
}
function json_preprocessor(p){
var new_object_array = [];
for (var key in p) {
if (p.hasOwnProperty(key)) {
var day_datum = format_day.parse(key);
var time_object = p[key];
var processed_times = times_preprocessor(time_object.sleeptimes);
new_object_array.push({
day: day_datum,
times: processed_times,
comments: time_object.comments,
glucose: time_object.glucose
});
}
}
return new_object_array;
}
function draw_graph(times){
var margin = {top: 20, right: 80, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
svg
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var main_group = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var tracks = main_group.append('g').classed('tracks', true)
var yindex = 0;
var begin_time, end_time;
var tab_height = 12;
var bar_height = 15;
var tab_ear = 4;
var vertical_skip = 17;
var time_offset_down = 6;
for (var item of times){
var mg = tracks.append('g');
for (var time_slot of item.times){
begin_time = get_ratio_from_time(time_slot[0]);
end_time = get_ratio_from_time(time_slot[1]);
var rec = mg.append('rect');
rec.attr("width", (end_time - begin_time) * width)
.attr("height", bar_height)
.style({fill: "#badcfc"})
.attr("transform", function(d){
return "translate(" + [
begin_time * width,
yindex * vertical_skip
] + ")"
})
}
var gg = tracks.append('g');
for (var reading of item.glucose){
var gtime = get_ratio_from_time(reading.time);
var gval = reading.value;
var ggroup = gg.append('g');
ggroup.attr({
transform: "translate(" + [0, (yindex * vertical_skip + 8)] + ")"})
var cl = ggroup.append('rect');
cl.attr({transform: "translate(" + [(gtime * width) + tab_ear , -6] +")"})
.attr({'height': tab_height})
.style({fill: get_color(gval).bg})
var cl2 = ggroup.append('path');
cl2.attr({transform: "translate(" + [(gtime * width) + tab_ear , -6] +")"})
.attr({'d': 'M' + [0,0,-tab_ear,tab_height/2,0,tab_height] + 'z'})
.style({fill: get_color(gval).bg})
var cltext = ggroup.append('text');
cltext.text(gval)
.attr({transform: "translate(" + [(gtime * width) + tab_ear , 4] +")"})
.attr({
'text-anchor': "start",
"font-size": 11,
"font-family": "sans-serif"
})
cltext.style({'fill': get_color(gval).tx })
var textwidth = cltext.node().getComputedTextLength();
cl.attr({'width': textwidth})
}
// draw comments
if (item.comments.length > 0){
var comment_group = mg.append('g');
comment_group.attr({
transform: "translate(" + [width + 20, yindex * vertical_skip] + ")"
})
var newrec = comment_group.append('rect')
newrec.attr('width', 20).attr('height', 13)
newrec.style({fill: "#fce7ba"})
}
yindex += 1;
mg.append('text')
.text(formatTime(item.day))
.attr("transform", "translate(-21," + (yindex * vertical_skip - 7) + ")")
.attr({'text-anchor': "middle", "font-size": 10, "font-family": "sans-serif"})
}
var indicat = main_group.append('g').classed('indications', true);
var ditimes = "00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24".split(" ");
var circle_push_vertical = 1.210360414208; // <---- use to push hourly circles up / down
var time_index = 0;
for (var tick of ditimes){
tick = tick + ":00";
var tgl = indicat.append('g');
var tl = tgl.append('line');
var xpostime = Math.floor(get_ratio_from_time(tick) * width);
tl.attr('x1', xpostime)
.attr('x2', xpostime)
.attr('y1', 0)
.attr('y2', height)
.style({"stroke-width": 1, stroke: "#cfdbe7"})
if (time_index % 3 === 0){
tl.style({"stroke-width": 1, stroke: "#aabfd4"})
var tcl = tgl.append('circle');
tcl.attr('cx', Math.floor(get_ratio_from_time(tick) * width))
.attr('cy', height/circle_push_vertical)
.attr('r', 16)
.style({fill: "#e0eeff"})
var txl = tgl.append('text');
txl.attr({
'text-anchor': "middle",
"font-size": 17,
"font-family": "sans-serif"
})
.attr(
'transform',
'translate(' + [
Math.floor(get_ratio_from_time(tick) * width),
(height/circle_push_vertical)+time_offset_down ] +
')')
.style({'fill': "#7c7c7c"})
.text(tick.slice(0,2))
}
time_index += 1;
}
}
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://d3js.org/d3-time.v0.2.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css" />
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
svg { width:100%; height: 100% }
</style>
</head>
<body>
<svg></svg>
<script src="dillitant.js"></script>
</body>
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axis text {
font: 10px sans-serif;
}
{
"2016/06/23": {
"comments": "",
"glucose": [
{
"time": "08:05",
"value": 7.22
},
{
"time": "12:58",
"value": 18.76
},
{
"time": "18:17",
"value": 25.64
},
{
"time": "22:45",
"value": 30.25
}
],
"times": ""
},
"2016/06/24": {
"comments": "",
"glucose": [
{
"time": "08:11",
"value": 7.44
},
{
"time": "12:25",
"value": 19.09
},
{
"time": "17:34",
"value": 23.76
},
{
"time": "22:05",
"value": 16.26
}
],
"times": ""
},
"2016/06/25": {
"comments": "",
"glucose": [
{
"time": "08:17",
"value": 9.66
},
{
"time": "12:23",
"value": 11.82
},
{
"time": "19:21",
"value": 22.37
},
{
"time": "22:49",
"value": 22.04
}
],
"times": ""
},
"2016/06/26": {
"comments": "",
"glucose": [
{
"time": "07:03",
"value": 7.44
},
{
"time": "12:24",
"value": 11.71
},
{
"time": "16:47",
"value": 20.65
},
{
"time": "16:50",
"value": 20.54
},
{
"time": "22:05",
"value": 20.93
}
],
"times": ""
},
"2016/06/27": {
"comments": "",
"glucose": [
{
"time": "07:32",
"value": 6.72
},
{
"time": "12:11",
"value": 14.76
},
{
"time": "16:46",
"value": 18.37
},
{
"time": "21:47",
"value": 21.04
}
],
"times": ""
},
"2016/06/28": {
"comments": "",
"glucose": [
{
"time": "08:04",
"value": 9.38
},
{
"time": "12:21",
"value": 23.53
},
{
"time": "17:17",
"value": 18.48
},
{
"time": "22:48",
"value": 22.31
}
],
"times": ""
},
"2016/06/29": {
"comments": "",
"glucose": [
{
"time": "07:40",
"value": 10.88
},
{
"time": "13:40",
"value": 17.48
},
{
"time": "18:45",
"value": 28.86
},
{
"time": "22:01",
"value": 20.54
}
],
"times": ""
},
"2016/06/30": {
"comments": "",
"glucose": [
{
"time": "08:08",
"value": 8.38
},
{
"time": "13:23",
"value": 21.65
},
{
"time": "20:08",
"value": 22.2
},
{
"time": "22:39",
"value": 23.15
}
],
"times": ""
},
"2016/07/01": {
"comments": "",
"glucose": [
{
"time": "08:07",
"value": 10.32
},
{
"time": "13:44",
"value": 21.2
},
{
"time": "17:37",
"value": 20.26
},
{
"time": "21:23",
"value": 15.82
}
],
"times": ""
},
"2016/07/02": {
"comments": "",
"glucose": [
{
"time": "07:41",
"value": 10.38
},
{
"time": "12:31",
"value": 18.93
},
{
"time": "18:52",
"value": 22.42
},
{
"time": "22:14",
"value": 17.6
}
],
"times": ""
},
"2016/07/03": {
"comments": "",
"glucose": [
{
"time": "07:33",
"value": 7.99
},
{
"time": "13:09",
"value": 17.1
},
{
"time": "16:09",
"value": 17.71
},
{
"time": "22:32",
"value": 20.98
}
],
"times": ""
},
"2016/07/04": {
"comments": "",
"glucose": [
{
"time": "08:08",
"value": 13.88
},
{
"time": "12:24",
"value": 25.14
},
{
"time": "14:09",
"value": 22.04
},
{
"time": "21:57",
"value": 10.55
}
],
"times": ""
},
"2016/07/05": {
"comments": "",
"glucose": [
{
"time": "08:09",
"value": 7.88
},
{
"time": "12:30",
"value": 8.05
},
{
"time": "17:51",
"value": 20.04
},
{
"time": "21:47",
"value": 16.26
}
],
"times": ""
},
"2016/07/06": {
"comments": "",
"glucose": [
{
"time": "07:25",
"value": 16.71
},
{
"time": "07:26",
"value": 16.32
},
{
"time": "12:07",
"value": 17.65
},
{
"time": "16:31",
"value": 19.7
},
{
"time": "21:49",
"value": 17.37
}
],
"times": ""
},
"2016/07/07": {
"comments": "",
"glucose": [
{
"time": "08:04",
"value": 11.49
},
{
"time": "11:54",
"value": 11.21
},
{
"time": "18:24",
"value": 16.04
},
{
"time": "21:31",
"value": 11.66
}
],
"times": ""
},
"2016/07/08": {
"comments": "",
"glucose": [
{
"time": "08:05",
"value": 9.99
},
{
"time": "13:43",
"value": 12.54
},
{
"time": "18:44",
"value": 18.04
},
{
"time": "21:33",
"value": 18.82
}
],
"times": ""
},
"2016/07/09": {
"comments": "",
"glucose": [
{
"time": "07:46",
"value": 7.94
},
{
"time": "12:49",
"value": 16.82
},
{
"time": "16:21",
"value": 12.93
},
{
"time": "22:04",
"value": 22.15
}
],
"times": ""
},
"2016/07/10": {
"comments": "",
"glucose": [
{
"time": "08:09",
"value": 7.55
},
{
"time": "12:50",
"value": 11.21
},
{
"time": "18:43",
"value": 22.65
},
{
"time": "21:37",
"value": 21.31
}
],
"times": ""
},
"2016/07/11": {
"comments": "",
"glucose": [
{
"time": "08:14",
"value": 11.27
},
{
"time": "12:30",
"value": 12.66
}
],
"times": ""
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment