Skip to content

Instantly share code, notes, and snippets.

@guypursey
Last active August 19, 2016 12:51
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 guypursey/ba66c98dd37e53be4eeb134897fcac85 to your computer and use it in GitHub Desktop.
Save guypursey/ba66c98dd37e53be4eeb134897fcac85 to your computer and use it in GitHub Desktop.
Journal entry visualisation
license: mit
Date Day Start time End time Total time Journal Start page End page Approx length Type
03/01/2016 Sunday 08:50 Brown 92 94 2 Reflection
04/01/2016 Monday 06:00 Brown 94 97 3 Description
05/01/2016 Tuesday 05:59 Brown 97 102 5 Reflection
05/01/2016 Tuesday 06:30 07:20 00:50 Tessellated 112 121 9 Account
06/01/2016 Wednesday 06:01 Brown 102 107 5 Memories
07/01/2016 Thursday 05:59 06:43 00:44 Brown 107 113 6 Dreams
08/01/2016 Friday 06:05 06:50 00:45 Brown 113 119 6 Observation
08/01/2016 Friday 05:59 06:18 00:19 Tessellated 135 138 3 Description
08/01/2016 Friday 17:00 17:27 00:27 Tessellated 138 143 5 Reflection
09/01/2016 Saturday 08:15 09:33 01:18 Brown 119 129 10 Reflection
10/01/2016 Sunday 07:25 07:58 00:33 Brown 129 133 4 Description
11/01/2016 Monday 06:00 06:23 00:23 Brown 133 136 3 Description
12/01/2016 Tuesday 06:03 06:38 00:35 Brown 136 141 5 Description
13/01/2016 Wednesday 06:03 06:35 00:32 Brown 141 146 5 Description
14/01/2016 Thursday 06:00 06:53 00:53 Brown 146 153 7 Memories
15/01/2016 Friday 06:00 06:37 00:37 Brown 153 158 5 Reflection
16/01/2016 Saturday 06:43 08:08 01:25 Brown 158 169 11 Description
16/01/2016 Saturday 16:00 16:16 00:16 Brown 169 172 3 Description
17/01/2016 Sunday 06:56 07:40 00:44 Brown 172 178 6 Reflection
17/01/2016 Sunday 16:00 16:15 00:15 Brown 178 180 2 Description
18/01/2016 Monday 06:00 06:19 00:19 Brown 180 183 3 Description
18/01/2016 Monday 17:00 17:17 00:17 Brown 183 187 4 Description
19/01/2016 Tuesday 06:00 06:28 00:28 Brown 187 190 3 Description
19/01/2016 Tuesday 18:00 Brown 190 192 2 Reflection
20/01/2016 Wednesday 05:59 06:43 00:44 Tessellated 1 8 7 Reflection
20/01/2016 Wednesday 18:00 18:15 00:15 Tessellated 8 12 4 Reflection
21/01/2016 Thursday 06:24 06:46 00:22 Tessellated 12 15 3 Description
21/01/2016 Thursday 10:00 10:15 00:15 Tessellated 15 19 4 Reflection
22/01/2016 Friday 06:12 06:36 00:24 Tessellated 19 24 5 Description
23/01/2016 Saturday 08:51 09:18 00:27 Tessellated 24 29 5 Description
24/01/2016 Sunday 07:24 08:00 00:36 Tessellated 29 32 3 Reflection
25/01/2016 Monday 06:12 06:34 00:22 Tessellated 32 37 5 Description
25/01/2016 Monday 18:00 18:16 00:16 Tessellated 37 41 4 Description
26/01/2016 Tuesday 06:08 06:49 00:41 Tessellated 41 48 7 Reflection
26/01/2016 Tuesday 12:33 12:49 00:16 Tessellated 48 52 4 Reflection
27/01/2016 Wednesday 06:13 06:45 00:32 Tessellated 52 57 5 Description
28/01/2016 Thursday 06:21 Tessellated 57 60 3 Description
28/01/2016 Thursday 18:00 18:17 00:17 Tessellated 60 64 4 Reflection
29/01/2016 Friday 06:34 06:55 00:21 Tessellated 64 68 4 Description
29/01/2016 Friday 18:00 18:16 00:16 Tessellated 68 72 4 Description
30/01/2016 Saturday 06:42 07:16 00:34 Tessellated 72 79 7 Description
31/01/2016 Sunday 07:24 07:52 00:28 Tessellated 79 84 5 Description
01/02/2016 Monday 05:04 05:28 00:24 Tessellated 84 90 6 Description
02/02/2016 Tuesday 06:00 06:39 00:39 Tessellated 90 98 8 Description
02/02/2016 Tuesday 18:10 18:33 00:23 Tessellated 98 104 6 Dialogue
03/02/2016 Wednesday 06:00 06:16 00:16 Tessellated 104 107 3 Dialogue
04/02/2016 Thursday 06:03 06:31 00:28 Tessellated 107 112 5 Description
06/02/2016 Saturday 09:12 09:44 00:32 Tessellated 121 127 6 Description
07/02/2016 Sunday 08:47 Tessellated 127 129 2 Description
07/02/2016 Sunday 17:00 17:24 00:24 Tessellated 129 135 6 Dialogue
09/02/2016 Tuesday 06:00 06:19 00:19 Tessellated 143 146 3 Description
10/02/2016 Wednesday 06:03 06:43 00:40 Tessellated 146 154 8 Reflection
11/02/2016 Thursday 06:02 06:41 00:39 Tessellated 154 162 8 Description
12/02/2016 Friday 06:02 06:32 00:30 Tessellated 162 167 5 Reflection
13/02/2016 Saturday 09:49 Tessellated 167 168 1 Description
13/02/2016 Saturday 17:03 17:20 00:17 Tessellated 168 172 4 Dialogue
14/02/2016 Sunday 08:14 08:35 00:21 Tessellated 172 176 4 Description
15/02/2016 Monday 06:30 06:50 00:20 Tessellated 176 180 4 Description
16/02/2016 Tuesday 06:17 06:30 00:13 Tessellated 180 183 3 Description
17/02/2016 Wednesday 06:17 06:43 00:26 Tessellated 183 188 5 Description
18/02/2016 Thursday 06:22 06:49 00:27 Tessellated 188 193 5 Description
19/02/2016 Friday 06:45 07:20 00:35 Tessellated 193 200 7 Reflection
20/02/2016 Saturday 06:42 07:49 01:07 Tessellated
22/02/2016 Monday 06:03 06:30 00:27 Tessellated
22/02/2016 Monday 06:30 06:51 00:21 Tessellated
23/02/2016 Tuesday 06:20 06:54 00:34 Tessellated
24/02/2016 Wednesday 06:36 06:53 00:17 Tessellated
25/02/2016 Thursday 07:34 08:13 00:39 Tessellated
26/02/2016 Friday 07:24 08:08 00:44 Tessellated
27/02/2016 Saturday 03:37 04:00 00:23 Tessellated
27/02/2016 Saturday 08:46 Tessellated
28/02/2016 Sunday 08:13 Tessellated
29/02/2016 Monday 08:00 Tessellated
02/03/2016 Wednesday 08:51 10:09 01:18 Dragonfly 1 15
03/03/2016 Thursday 06:00 06:34 00:34 Dragonfly
03/03/2016 Thursday 19:00 19:34 00:34 Dragonfly
04/03/2016 Friday 06:00 06:40 00:40 Dragonfly
05/03/2016 Saturday 18:47 18:55 00:08 Dragonfly
06/03/2016 Sunday 07:33 08:27 00:54 Dragonfly
07/03/2016 Monday 06:02 06:15 00:13 Dragonfly
08/03/2016 Tuesday 06:05 06:33 00:28 Dragonfly
08/03/2016 Tuesday 07:40 07:50 00:10 Dragonfly
09/03/2016 Wednesday 05:59 06:38 00:39 Dragonfly
10/03/2016 Thursday 06:05 06:43 00:38 Dragonfly
11/03/2016 Friday 06:30 06:41 00:11 Dragonfly
12/03/2016 Saturday 07:16 07:41 00:25 Dragonfly
13/03/2016 Sunday 08:55 09:10 00:15 Dragonfly
14/03/2016 Monday 06:08 06:46 00:38 Dragonfly
15/03/2016 Tuesday 06:05 06:34 00:29 Dragonfly
16/03/2016 Wednesday 06:13 06:44 00:31 Dragonfly
17/03/2016 Thursday 06:20 06:50 00:30 Dragonfly
18/03/2016 Friday 06:48 07:19 00:31 Dragonfly
19/03/2016 Saturday 09:08 09:22 00:14 Dragonfly
20/03/2016 Sunday 06:59 07:20 00:21 Dragonfly
21/03/2016 Monday 06:04 06:45 00:41 Dragonfly
22/03/2016 Tuesday 06:10 07:07 00:57 Dragonfly
23/03/2016 Wednesday 06:25 06:56 00:31 Dragonfly
24/03/2016 Thursday 06:38 06:50 00:12 Dragonfly
25/03/2016 Friday 08:15 Dragonfly
26/03/2016 Saturday 07:56 08:49 00:53 Dragonfly
27/03/2016 Sunday 07:13 07:32 00:19 Dragonfly
28/03/2016 Monday 06:00 07:20 01:20 Dragonfly
29/03/2016 Tuesday 08:04 08:35 00:31 Dragonfly
30/03/2016 Wednesday 06:11 06:40 00:29 Dragonfly
31/03/2016 Thursday 06:00 06:21 00:21 Dragonfly
01/04/2016 Friday 06:21 06:57 00:36 Dragonfly
02/04/2016 Saturday 07:35 07:55 00:20 Dragonfly
03/04/2016 Sunday 07:04 07:49 00:45 Dragonfly
04/04/2016 Monday 05:59 06:16 00:17 Dragonfly
05/04/2016 Tuesday 06:00 06:19 00:19 Dragonfly
06/04/2016 Wednesday 06:04 06:43 00:39 Dragonfly
07/04/2016 Thursday 06:20 06:38 00:18 Dragonfly
08/04/2016 Friday 06:38 06:44 00:06 Dragonfly
09/04/2016 Saturday 08:03 08:47 00:44 Dragonfly
10/04/2016 Sunday 08:13 08:54 00:41 Dragonfly
11/04/2016 Monday 05:59 06:24 00:25 Dragonfly
12/04/2016 Tuesday 06:15 06:30 00:15 Dragonfly
13/04/2016 Wednesday 06:26 06:52 00:26 Dragonfly
14/04/2016 Thursday 06:38 06:50 00:12 Dragonfly
15/04/2016 Friday 06:29 06:43 00:14 Dragonfly
16/04/2016 Saturday 09:04 09:51 00:47 Dragonfly
17/04/2016 Sunday 06:30 06:41 00:11 Dragonfly
18/04/2016 Monday 05:57 06:13 00:16 Dragonfly
19/04/2016 Tuesday 06:26 06:44 00:18 Dragonfly
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.grid .tick {
stroke: lightgrey;
opacity: 0.7;
}
.grid path {
stroke-width: 0;
}
.axis {
shape-rendering: crispEdges;
}
.axis line {
fill: none;
shape-rendering: crispEdges;
}
.y.axis line, .y.axis path {
fill: none;
stroke: lightgrey;
}
.bar {
fill: steelblue;
}
.bar:hover {
fill: brown;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.chart {
position: relative;
}
.tooltip {
background: #eee;
box-shadow: 0 0 5px #999999;
color: #333;
display: none;
font-size: 12px;
left: 130px;
padding: 10px;
position: absolute;
text-align: center;
top: 95px;
width: 80px;
z-index: 10;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var getDayName = function (day_number) {
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
var day_name = ""
if (typeof day_number === "number") {
day_name = days[parseInt(day_number, 10) % 7] || ""
}
return day_name
}
var getMonthName = function (month_number) {
var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
var month_name = ""
if (typeof month_number === "number") {
month_name = months[parseInt(month_number, 10) % 12] || ""
}
return month_name
}
var margin = {top: 40, right: 40, bottom: 40, left: 40}
var width = 960
var height = 500
var svg = d3.select("body").append("svg")
.attr("class", "chart")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`)
var tooltip = d3.select('body')
.append('div')
.attr('class', 'tooltip')
tooltip.append('div')
.attr('class', 'label')
tooltip.append('div')
.attr('class', 'count')
tooltip.append('div')
.attr('class', 'percent')
d3.tsv("data.tsv", cleanUpData, function(error, data) {
if (error) throw error;
var x = d3.time.scale()
.domain([data[0].date, d3.time.day.offset(data[data.length - 1].date, 1)])
.rangeRound([0, width - margin.left - margin.right])
var y = d3.time.scale()
.domain([new Date(0, 0, 0, 0, 0), new Date(0, 0, 1, 0, 0)])
.range([height - margin.top - margin.bottom, 0])
var color = d3.scale.category10()
var uniqueTypes = {}
var typeKeyArray = data
.map(r => r["Type"])
.filter(r => uniqueTypes[r] = (typeof uniqueTypes[r] === "undefined"))
.filter(r => r)
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.days, 32)
.tickFormat(d3.time.format("%B %Y"))
.tickSize(5)
.tickPadding(1)
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(d3.time.hours, 1)
.tickFormat(d3.time.format("%H:%M"))
.tickSize(10)
.tickPadding(0)
svg.append("g")
.attr("class", "x axis")
.attr("transform", `translate(0, ${height - margin.top - margin.bottom})`)
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Total time")
//Draw a grid
var yAxisGrid = yAxis.scale(y).ticks(d3.time.hours, 1)
.tickSize(width - margin.left - margin.right, 0)
.tickFormat("")
.orient("right");
var xAxisGrid = xAxis.scale(x).ticks(d3.time.days, 1)
.tickSize(-(height - margin.top - margin.bottom), 0)
.tickFormat("")
.orient("top");
svg.append("g")
.classed('y', true)
.classed('grid', true)
.call(yAxisGrid);
svg.append("g")
.classed('x', true)
.classed('grid', true)
.call(xAxisGrid);
svg.selectAll(".chart")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", d => x(d.date))
.attr("y", d => y(d.end))
.attr("width", width / data.length)
.attr("height", d => y(d.start) - y(d.end))
.style("fill", d => color(d["Type"]))
.on('mouseover', function(d) {
tooltip.select('.label').html(d["Type"]);
tooltip.select('.count').html(`${getDayName(d.date.getDay())}, ${d.date.getDate()} ${getMonthName(d.date.getMonth())} ${d.date.getFullYear()}`);
tooltip.style('display', 'block');
})
.on('mouseout', function() {
tooltip.style('display', 'none');
})
.on('mousemove', function(d) {
tooltip.style('top', (d3.event.layerY + 10) + 'px')
.style('left', (d3.event.layerX + 10) + 'px');
})
var legend = svg.selectAll(".legend")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", (d, i) => `translate(0, ${i * 20})`)
legend.append("rect")
.attr("x", width - margin.right - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color)
legend.append("text")
.attr("x", width - margin.right - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(d => d)
})
function cleanUpData (d) {
d["date"] = convertUKDateToISO(d["Date"])
d["start"] = convertTimeToJSDateTime(d["Start time"])
d["end"] = convertTimeToJSDateTime(d["End time"])
d["total"] = convertTimeToJSDateTime(d["Total time"])
d["Type"] = fillBlankType(d["Type"])
return d.date && d.start && d.end && d.total && d
}
function fillBlankType (d) {
return d || "No type given"
}
function convertTimeToJSDateTime (t) {
var minutes = /:(\d\d)$/.exec(t) || [ null, null ]
var hours = /^(\d\d):/.exec(t) || [ null, null ]
t = hours[1] && minutes[1] && new Date(0, 0, 0, hours[1], minutes[1])
//console.log(t)
return t
}
function convertUKDateToISO (d) {
var d = d.split("/")
d = d.length === 3 ? `${d[2]}-${d[1]}-${d[0]}` : null
d = new Date(d)
return d
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment