Skip to content

Instantly share code, notes, and snippets.

@zeffii
Last active April 8, 2016 15:27
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 zeffii/4a7b3135dd1dfba1e1e69d575a68bcd5 to your computer and use it in GitHub Desktop.
Save zeffii/4a7b3135dd1dfba1e1e69d575a68bcd5 to your computer and use it in GitHub Desktop.
sleep_tkd - nested v2
/*
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:
....
"01/04/2016": {
"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("%d/%m/%Y");
var format_hours = d3.time.format("%H:%M");
var formatTime = d3.time.format("%m / %d"); // formatTime(new Date); // "June 30, 2015"
d3.json("times.json", function(error, times) {
if (error) throw error;
times = json_preprocessor(times);
draw_graph(times);
});
function times_preprocessor(t){
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 bar_height = 15;
var vertical_skip = 17;
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 , -6] +")"})
.attr({'height': 12})
.style({fill: get_color(gval).bg})
var cltext = ggroup.append('text');
cltext.text(gval)
.attr({transform: "translate(" + [gtime * width , 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})
}
yindex += 1;
mg.append('text')
.text(formatTime(item.day))
.attr("transform", "translate(-21," + (yindex * vertical_skip - 3) + ")")
.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.36;
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)+5 ] +
')')
.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;
}
{
"21/03/2016": {
"sleeptimes": "10:30->12:00,13:45->15:00,16:21->17:30,21:15->22:15,22:25->24:00",
"comments": "",
"glucose": [
{"time": "06:32", "value": 10.16},
{"time": "12:12", "value": 16.76},
{"time": "17:43", "value": 18.76},
{"time": "22:13", "value": 22.42}
]
},
"22/03/2016": {
"sleeptimes": "00:00->01:00,01:05->02:00,02:05->03:53,04:05->05:30,09:45->12:00,14:20->16:45,19:45->22:00,22:40->24:00",
"comments": "",
"glucose": [
{"time": "06:32", "value": 8.49},
{"time": "12:00", "value": 20.32},
{"time": "17:43", "value": 21.59},
{"time": "22:19", "value": 19.48}
]
},
"23/03/2016": {
"sleeptimes": "00:00->01:15,01:20->07:12,09:45->12:00,16:00->17:45,20:15->22:00,22:15->24:00",
"comments": "",
"glucose": [
{"time": "07:23", "value": 7.27},
{"time": "12:02", "value": 15.54},
{"time": "17:53", "value": 19.43},
{"time": "22:27", "value": 21.15}
]
},
"24/03/2016": {
"sleeptimes": "00:00->05:10,05:20->07:00,09:40->11:10,13:52->16:00,19:30->21:30,23:10->24:00",
"comments": "",
"glucose": [
{"time": "07:17", "value": 9.6},
{"time": "12:13", "value": 22.26},
{"time": "17:11", "value": 19.98},
{"time": "23:02", "value": 17.65}
]
},
"25/03/2016": {
"sleeptimes": "00:00->07:00,09:22->11:15,12:45->14:40,17:30->17:50,20:00->20:53,22:20->24:00",
"comments": "",
"glucose": [
{"time": "07:10", "value": 6.11},
{"time": "11:57", "value": 10.27},
{"time": "17:47", "value": 23.37},
{"time": "21:56", "value": 23.37}
]
},
"26/03/2016": {
"sleeptimes": "00:00->07:00,09:20->11:45,14:15->17:30,22:10->24:00",
"comments": "",
"glucose": [
{"time": "07:02", "value": 8.6},
{"time": "11:40", "value": 20.43},
{"time": "17:36", "value": 20.32},
{"time": "21:34", "value": 17.32}
]
},
"27/03/2016": {
"sleeptimes": "00:00->06:00,10:50->11:45,13:20->14:52,16:30->17:00,19:00->20:44,22:15->24:00",
"comments": "",
"glucose": [
{"time": "06:40", "value": 9.05},
{"time": "10:44", "value": 15.71},
{"time": "16:31", "value": 21.31},
{"time": "21:03", "value": 17.93}
]
},
"28/03/2016": {
"sleeptimes": "00:00->06:00,22:15->24:00",
"comments": "",
"glucose": [
{"time": "06:23", "value": 6.88},
{"time": "10:15", "value": 13.04},
{"time": "16:43", "value": 13.93},
{"time": "20:26", "value": 15.38}
]
},
"29/03/2016": {
"sleeptimes": "00:00->07:00,16:00->18:50,21:20->24:00",
"comments": "AMC visit Dr Soeters, Novomix 78-48",
"glucose": [
{"time": "07:29", "value": 7.72},
{"time": "12:40", "value": 13.99},
{"time": "19:07", "value": 19.15},
{"time": "21:22", "value": 19.04}
]
},
"30/03/2016": {
"sleeptimes": "00:00->06:30,09:30->11:30,15:30->18:15,22:00->24:00",
"comments": "",
"glucose": [
{"time": "07:18", "value": 5.77},
{"time": "11:31", "value": 20.87},
{"time": "17:33", "value": 15.43},
{"time": "20:40", "value": 15.43}
]
},
"31/03/2016": {
"sleeptimes": "00:00->05:30,08:00->10:30,11:15->13:00,15:20->16:20,17:20->17:45,20:30->22:45,23:15->24:00",
"comments": "",
"glucose": [
{"time": "06:00", "value": 5.83},
{"time": "10:54", "value": 14.99},
{"time": "17:07", "value": 18.26},
{"time": "19:57", "value": 16.6}
]
},
"01/04/2016": {
"sleeptimes": "00:00->06:35,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}
]
},
"02/04/2016": {
"sleeptimes": "00:00->07:00,07:15->08:00,09:30->12:45,16:05->17:45,20:30->21:00,22:15->24:00",
"comments": "",
"glucose": [
{"time": "08:21", "value": 9.27},
{"time": "12:47", "value": 18.87},
{"time": "18:14", "value": 17.76},
{"time": "22:08", "value": 16.82}
]
},
"03/04/2016": {
"sleeptimes": "00:00->06:30,08:10->11:30,14:30->18:30,21:00->22:40,23:00->24:00",
"comments": "",
"glucose": [
{"time": "07:12", "value": 8.38},
{"time": "11:50", "value": 12.88},
{"time": "18:24", "value": 16.32},
{"time": "22:44", "value": 11.93}
]
},
"04/04/2016": {
"sleeptimes": "00:00->07:00,09:00->11:30,15:30->17:30,22:00->24:00",
"comments": "",
"glucose": [
{"time": "07:38", "value": 9.21},
{"time": "12:51", "value": 13.32},
{"time": "18:13", "value": 13.1},
{"time": "21:50", "value": 14.4}
]
},
"05/04/2016": {
"sleeptimes": "00:00->06:50,09:20->12:00,13:50->15:30,21:50->24:00",
"comments": "Grandad arrives from Ireland",
"glucose": [
{"time": "06:58", "value": 6.4},
{"time": "12:51", "value": 17.2},
{"time": "18:22", "value": 14.9},
{"time": "21:37", "value": 21.8}
]
},
"06/04/2016": {
"sleeptimes": "00:00->07:00,10:00->12:15,15:30->17:25,20:50->22:05,22:30->24:00",
"comments": "",
"glucose": [
{"time": "22:17", "value": 14.99},
{"time": "17:45", "value": 23.87},
{"time": "12:22", "value": 16.71},
{"time": "08:16", "value": 6.27}
]
},
"07/04/2016": {
"sleeptimes": "00:00->07:00,07:10->08:00,10:30->12:05,15:50->17:30,22:05->24:00",
"comments": "had fruit shortly before night-time measurement...|Nadifa increased NM to 82-50",
"glucose": [
{"time": "21:53", "value": 22.92},
{"time": "17:57", "value": 19.59},
{"time": "12:12", "value": 19.26},
{"time": "08:06", "value": 5.72}
]
},
"08/04/2016": {
"sleeptimes": "00:00->07:00,9:00->11:15",
"comments": "",
"glucose": [
{"time": "07:11", "value": 9.44}
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment