Journal entries visualised as a ranged bar chart, as described in my blog post on visualising journal entries.
Last active
August 19, 2016 12:51
-
-
Save guypursey/ba66c98dd37e53be4eeb134897fcac85 to your computer and use it in GitHub Desktop.
Journal entry visualisation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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