This is my first foray into D3. This project was to try out the fundamentals of the library that I have learnt so far.
Last active
January 11, 2021 18:25
-
-
Save bigarabuza/3fc12643286ee7acda76bd9d96d89635 to your computer and use it in GitHub Desktop.
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
Activity Type | Date | Favorite | Title | Distance | Calories | Time | Avg Run Cadence | Max Run Cadence | Avg Pace | Best Pace | Elev Gain | Elev Loss | Avg Stride Length | Avg Vertical Ratio | Avg Vertical Oscillation | Training Stress Score® | Grit | Flow | Climb Time | Bottom Time | Min Temp | Surface Interval | Decompression | Best Lap Time | Number of Laps | Max Temp | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Running | 2021-01-05 14:55:56 | false | Philadelphia Running | 3.16 | 416 | 00:22:18 | 177 | 219 | 7:03 | 4:14 | 39 | 39 | 1.29 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:18 | 0:00 | 0.0 | 0:00 | No | 01:12.72 | 4 | 0.0 | |
Running | 2021-01-03 16:44:58 | false | Philadelphia Running | 3.21 | 410 | 00:23:11 | 177 | 219 | 7:13 | 5:09 | 39 | 39 | 1.26 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:11 | 0:00 | 0.0 | 0:00 | No | 01:30.39 | 4 | 0.0 | |
Running | 2021-01-01 09:19:52 | false | Philadelphia Running | 3.22 | 407 | 00:22:57 | 177 | 189 | 7:08 | 6:15 | 39 | 39 | 1.27 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:57 | 0:00 | 0.0 | 0:00 | No | 01:44.48 | 4 | 0.0 | |
Running | 2020-12-30 14:09:31 | false | Philadelphia Running | 3.17 | 398 | 00:22:45 | 177 | 204 | 7:10 | 4:46 | 39 | 39 | 1.27 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:45 | 0:00 | 0.0 | 0:00 | No | 01:10.96 | 4 | 0.0 | |
Running | 2020-12-28 08:26:15 | false | Philadelphia Running | 3.19 | 402 | 00:22:39 | 177 | 188 | 7:07 | 6:00 | 40 | 39 | 1.28 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:39 | 0:00 | 0.0 | 0:00 | No | 01:15.73 | 4 | 0.0 | |
Running | 2020-12-26 15:43:34 | false | Randolph Running | 2.22 | 288 | 00:17:48 | 171 | 184 | 8:01 | 6:13 | 334 | 314 | 1.18 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 17:48 | 0:00 | 0.0 | 0:00 | No | 01:54.44 | 3 | 0.0 | |
Running | 2020-12-23 09:31:19 | false | Philadelphia Running | 3.23 | 406 | 00:23:14 | 176 | 191 | 7:12 | 5:48 | 37 | 37 | 1.27 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:14 | 0:00 | 0.0 | 0:00 | No | 01:32.19 | 4 | 0.0 | |
Running | 2020-12-21 14:32:10 | false | Philadelphia Running | 5.12 | 641 | 00:37:22 | 176 | 204 | 7:17 | 4:14 | 56 | 59 | 1.26 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 37:22 | 0:00 | 0.0 | 0:00 | No | 00:58.91 | 6 | 0.0 | |
Running | 2020-12-14 08:41:27 | false | Philadelphia Running | 3.17 | 407 | 00:23:26 | 177 | 186 | 7:24 | 5:33 | 39 | 39 | 1.23 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:26 | 0:00 | 0.0 | 0:00 | No | 01:17.66 | 4 | 0.0 | |
Running | 2020-12-12 20:23:13 | false | Philadelphia Running | 6.00 | 786 | 00:44:03 | 177 | 185 | 7:21 | 2:09 | 93 | 93 | 1.24 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 44:03 | 0:00 | 0.0 | 0:00 | No | 07:04.90 | 6 | 0.0 | |
Running | 2020-12-10 12:53:41 | false | Philadelphia Running | 3.20 | 408 | 00:23:06 | 177 | 187 | 7:13 | 5:44 | 39 | 39 | 1.26 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:06 | 0:00 | 0.0 | 0:00 | No | 01:26.12 | 4 | 0.0 | |
Running | 2020-12-08 14:36:13 | false | Philadelphia Running | 3.23 | 418 | 00:23:28 | 175 | 190 | 7:16 | 4:55 | 39 | 39 | 1.26 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:28 | 0:00 | 0.0 | 0:00 | No | 01:32.26 | 4 | 0.0 | |
Running | 2020-12-06 14:16:50 | false | Philadelphia Running | 6.14 | 793 | 00:45:17 | 176 | 197 | 7:23 | 5:01 | 76 | 76 | 1.24 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 45:17 | 0:00 | 0.0 | 0:00 | No | 00:55.45 | 7 | 0.0 | |
Running | 2020-12-04 08:19:20 | false | Philadelphia Running | 3.26 | 426 | 00:22:50 | 176 | 219 | 7:01 | 5:25 | 39 | 39 | 1.30 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:50 | 0:00 | 0.0 | 0:00 | No | 01:47.71 | 4 | 0.0 | |
Running | 2020-12-01 08:23:48 | false | Philadelphia Running | 3.19 | 414 | 00:23:08 | 175 | 185 | 7:15 | 5:33 | 43 | 43 | 1.27 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:08 | 0:00 | 0.0 | 0:00 | No | 01:18.93 | 4 | 0.0 | |
Running | 2020-11-29 09:10:41 | false | Philadelphia Running | 3.29 | 421 | 00:23:00 | 176 | 184 | 7:00 | 4:51 | 38 | 37 | 1.31 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:00 | 0:00 | 0.0 | 0:00 | No | 02:00.00 | 4 | 0.0 | |
Running | 2020-11-28 11:02:31 | false | Philadelphia Running | 3.20 | 410 | 00:22:32 | 176 | 187 | 7:03 | 5:24 | 39 | 38 | 1.30 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:32 | 0:00 | 0.0 | 0:00 | No | 01:20.88 | 4 | 0.0 | |
Running | 2020-11-25 16:14:51 | false | Philadelphia Running | 3.24 | 414 | 00:22:55 | 175 | 184 | 7:04 | 5:51 | 38 | 37 | 1.30 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:55 | 0:00 | 0.0 | 0:00 | No | 01:44.01 | 4 | 0.0 | |
Running | 2020-11-23 12:15:44 | false | Philadelphia Running | 3.40 | 425 | 00:23:10 | 177 | 184 | 6:49 | 2:27 | 40 | 39 | 1.34 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:10 | 0:00 | 0.0 | 0:00 | No | 02:50.47 | 4 | 0.0 | |
Running | 2020-11-22 09:12:00 | false | Philadelphia Running | 3.18 | 408 | 00:22:50 | 177 | 185 | 7:10 | 5:06 | 39 | 39 | 1.27 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:50 | 0:00 | 0.0 | 0:00 | No | 01:19.92 | 4 | 0.0 | |
Running | 2020-11-20 08:33:36 | false | Philadelphia Running | 3.19 | 414 | 00:22:49 | 177 | 185 | 7:09 | 4:55 | 42 | 42 | 1.27 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:49 | 0:00 | 0.0 | 0:00 | No | 01:22.43 | 4 | 0.0 | |
Running | 2020-11-16 07:50:14 | false | Philadelphia Running | 3.15 | 405 | 00:23:03 | 175 | 184 | 7:19 | 5:15 | 38 | 38 | 1.26 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:03 | 0:00 | 0.0 | 0:00 | No | 01:04.64 | 4 | 0.0 | |
Running | 2020-11-15 08:48:35 | false | Philadelphia Running | 4.13 | 535 | 00:30:13 | 175 | 184 | 7:19 | 4:36 | 56 | 53 | 1.25 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 30:13 | 0:00 | 0.0 | 0:00 | No | 00:52.73 | 5 | 0.0 | |
Running | 2020-11-11 05:22:16 | false | Philadelphia Running | 3.25 | 421 | 00:23:16 | 176 | 182 | 7:09 | 4:00 | 42 | 42 | 1.28 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:16 | 0:00 | 0.0 | 0:00 | No | 01:45.78 | 4 | 0.0 | |
Running | 2020-11-08 06:42:24 | false | Philadelphia Running | 3.11 | 404 | 00:22:52 | 175 | 184 | 7:21 | 4:58 | 43 | 43 | 1.25 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:52 | 0:00 | 0.0 | 0:00 | No | 00:47.50 | 4 | 0.0 | |
Running | 2020-11-05 18:02:59 | false | Philadelphia Running | 3.24 | 401 | 00:23:12 | 172 | 192 | 7:10 | 4:39 | 39 | 39 | 1.30 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:12 | 0:00 | 0.0 | 0:00 | No | 01:43.05 | 4 | 0.0 | |
Running | 2020-11-04 19:22:32 | false | Philadelphia Running | 3.21 | 423 | 00:23:16 | 175 | 183 | 7:15 | 5:31 | 35 | 35 | 1.27 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:16 | 0:00 | 0.0 | 0:00 | No | 01:30.16 | 4 | 0.0 | |
Running | 2020-10-31 10:39:49 | false | Philadelphia Running | 4.16 | 544 | 00:30:36 | 179 | 186 | 7:21 | 6:03 | 19 | 27 | 1.22 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 30:36 | 0:00 | 0.0 | 0:00 | No | 01:10.48 | 5 | 0.0 | |
Running | 2020-10-24 06:36:49 | false | Randolph Running | 3.29 | 407 | 00:27:52 | 169 | 224 | 8:28 | 6:47 | 500 | 474 | 1.12 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 27:52 | 0:00 | 0.0 | 0:00 | No | 02:38.74 | 4 | 0.0 | |
Running | 2020-10-19 05:29:01 | false | Philadelphia Running | 3.15 | 419 | 00:23:19 | 177 | 186 | 7:24 | 6:09 | 42 | 38 | 1.23 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:19 | 0:00 | 0.0 | 0:00 | No | 01:06.94 | 4 | 0.0 | |
Running | 2020-10-18 07:51:27 | false | Philadelphia Running | 3.22 | 419 | 00:23:35 | 177 | 183 | 7:20 | 6:08 | 41 | 41 | 1.24 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23:35 | 0:00 | 0.0 | 0:00 | No | 01:32.29 | 4 | 0.0 | |
Running | 2020-10-09 08:27:18 | false | Philadelphia Running | 3.16 | 402 | 00:22:53 | 177 | 189 | 7:15 | 6:05 | 38 | 38 | 1.25 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:53 | 0:00 | 0.0 | 0:00 | No | 01:01.55 | 4 | 0.0 | |
Running | 2020-10-06 05:21:07 | false | Philadelphia Running | 3.15 | 403 | 00:22:34 | 177 | 184 | 7:10 | 4:24 | 38 | 39 | 1.27 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:34 | 0:00 | 0.0 | 0:00 | No | 01:01.15 | 4 | 0.0 | |
Running | 2020-10-03 13:59:53 | false | Philadelphia Running | 3.15 | 394 | 00:22:12 | 175 | 185 | 7:02 | 4:47 | 43 | 43 | 1.31 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22:12 | 0:00 | 0.0 | 0:00 | No | 01:01.88 | 4 | 0.0 |
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> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<link href="style.css" rel="stylesheet" /> | |
<script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script> | |
<script | |
src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" | |
integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" | |
crossorigin="anonymous" | |
></script> | |
<script> | |
moment().format(); | |
</script> | |
<title>Running Data Viz</title> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
"use strict"; | |
const w = 500, | |
h = 300, | |
marginW = 50, | |
marginH = 30; | |
let svg = d3 | |
.select("body") | |
.append("svg") | |
.attr("width", w) | |
.attr("height", h); | |
const xScale = d3.scaleTime().range([marginW, w - marginW]); | |
const yScale = d3.scaleLinear().range([h - marginH, marginH]); | |
const formatDate = d3.timeFormat("%b %e"); | |
const xAxis = d3 | |
.axisBottom(xScale) | |
.tickFormat(function (d) { | |
return formatDate(d); | |
}) | |
.tickSize(h - marginH * 2 + 10) | |
.tickPadding(2); | |
const yAxis = d3 | |
.axisLeft(yScale) | |
.tickFormat(function (d) { | |
return moment.utc(d).format("mm:ss"); | |
}) | |
.tickSize(w - marginW * 2 + 10) | |
.tickPadding(2); | |
// Data set-up | |
const data = {}; | |
const parseDate = d3.timeParse("%Y-%m-%d %H:%M:%S"); | |
const regexpTime = /([0-9]+):([0-9]+)/; | |
let rowConverter = function (d) { | |
let matchedTimeGrps = d["Avg Pace"].match(regexpTime); | |
return { | |
Date: parseDate(d["Date"]), | |
Pace: moment.duration({ | |
minutes: matchedTimeGrps[1], | |
seconds: matchedTimeGrps[2], | |
}), | |
}; | |
}; | |
d3.csv("garmin_download.csv", rowConverter).then(function (dataset) { | |
data.runs = dataset; | |
xScale.domain(d3.extent(dataset, (d) => d.Date)); | |
yScale.domain(d3.extent(dataset, (d) => d.Pace)); | |
drawAxes(); | |
drawPoints(); | |
drawTooltips(); | |
drawTitle(); | |
}); | |
function drawPoints() { | |
d3.select("svg") | |
.selectAll("circle") | |
.data(data.runs) | |
.enter() | |
.append("circle") | |
.attr("cx", (d) => xScale(d.Date)) | |
.attr("cy", (d) => yScale(d.Pace)) | |
.attr("r", 2) | |
.on("mouseenter", showDetails) | |
.on("mouseleave", clearDetails); | |
} | |
function drawAxes() { | |
//Axes | |
const xG = d3 | |
.select("svg") | |
.append("g") | |
.attr("class", "x-axis") | |
.attr("transform", `translate(${[0, marginH]})`) | |
.call(xAxis); | |
const yG = d3 | |
.select("svg") | |
.append("g") | |
.attr("class", "y-axis") | |
.attr("transform", `translate(${[w - marginW, 0]})`) | |
.call(yAxis); | |
//Labels to axes | |
d3.select("svg") | |
.append("text") | |
.attr("class", "label") | |
.text("Date") | |
.attr("transform", `translate(${[w / 2, h - 1]})`); | |
d3.select("svg") | |
.append("text") | |
.attr("class", "label") | |
.text("Pace (min/mi)") | |
.attr("transform", `translate(${[1, h / 2]}) rotate(90)`); | |
} | |
function drawTooltips() { | |
const tooltip = d3 | |
.select("svg") | |
.append("g") | |
.attr("class", "tooltip") | |
.attr("opacity", 0); | |
tooltip | |
.append("rect") | |
.attr("width", 80) | |
.attr("height", 45) | |
.attr("rx", 3) | |
.attr("ry", 3) | |
.attr("x", -3) | |
.attr("y", -2); | |
tooltip.append("text").attr("class", "dt").attr("y", 15); | |
tooltip.append("text").attr("class", "pace").attr("y", 30); | |
} | |
function showDetails(d) { | |
d3.select(this).attr("r", 4); | |
d3.select(".tooltip") | |
.attr("opacity", 1) | |
.attr( | |
"transform", | |
`translate(${[10 + xScale(d.Date), yScale(d.Pace) - 20]})` | |
); | |
const text1 = d3 | |
.select(".tooltip .dt") | |
.text("Date: " + formatDate(d.Date)); | |
const text2 = d3 | |
.select(".tooltip .pace") | |
.text("Pace: " + moment.utc(d.Pace.asMilliseconds()).format("mm:ss")); | |
const boxWidth = | |
6 + | |
d3.max([ | |
text1.node().getComputedTextLength(), | |
text2.node().getComputedTextLength(), | |
]); | |
d3.select(".tooltip rect").attr("width", boxWidth); | |
} | |
function clearDetails(d) { | |
d3.select(this).attr("r", 2); | |
d3.select(".tooltip").attr("opacity", 0); | |
} | |
function drawTitle() { | |
d3.select("svg") | |
.append("text") | |
.attr("transform", `translate(${[w / 2, marginH - 10]})`) | |
.style("text-anchor", "middle") | |
.style("font-size", "16px") | |
.text("Past 3 Month Runs"); | |
} | |
</script> | |
</body> | |
</html> |
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
text { | |
font-family: "Yanone Kaffeesatz", "Arial Narrow", sans-serif; | |
font-size: 7pt; | |
} | |
.label { | |
font-size: 9pt; | |
text-anchor: middle; | |
} | |
.domain { | |
opacity: 0; | |
} | |
.y-axis line, | |
.x-axis line { | |
stroke-width: 0.25; | |
stroke: rgba(114, 138, 74, 0.5); | |
} | |
.tooltip { | |
pointer-events: none; | |
} | |
.tooltip rect { | |
fill: #eee; | |
fill-opacity: 0.8; | |
stroke: gray; | |
stroke-opacity: 0.5; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment