Skip to content

Instantly share code, notes, and snippets.

@ajpierce
Last active August 29, 2015 14:01
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 ajpierce/906607f0bc428a6e2317 to your computer and use it in GitHub Desktop.
Save ajpierce/906607f0bc428a6e2317 to your computer and use it in GitHub Desktop.
2014 Cardio Activities
Date Type Route Name Distance (mi) Duration Average Pace Average Speed (mph) Calories Burned Climb (ft) Average Heart Rate (bpm) Notes GPX File
2014-05-20 10:08:26 Running 5.82 53:15 9:09 6.56 772.0 81.91 156 2014-05-20-1008.gpx
2014-05-19 09:54:10 Running 6.06 55:37 9:11 6.53 805.0 88.92 157 2014-05-19-0954.gpx
2014-05-17 09:30:36 Running 2.11 15:48 7:30 8.00 282.0 29.79 172 2014-05-17-0930.gpx
2014-05-15 09:37:01 Running 4.74 44:48 9:27 6.35 629.0 81.45 160 2014-05-15-0937.gpx
2014-05-13 09:04:32 Running 2.25 19:27 8:38 6.95 300.0 31.36 158 2014-05-13-0904.gpx
2014-05-08 09:50:47 Running 2.25 18:28 8:12 7.32 299.0 31.21 165 2014-05-08-0950.gpx
2014-05-06 10:22:11 Running 8.02 1:14:35 9:18 6.45 1066.0 136.00 160 2014-05-06-1022.gpx
2014-05-05 10:56:44 Running 2.25 18:04 8:02 7.47 298.0 29.64 166 2014-05-05-1056.gpx
2014-05-02 10:18:15 Running 6.26 57:50 9:14 6.50 831.0 102.09 159 2014-05-02-1018.gpx
2014-04-28 10:33:10 Running 2.27 18:57 8:21 7.19 300.0 30.47 159 2014-04-28-1033.gpx
2014-04-26 09:03:39 Running 6.23 54:19 8:43 6.88 822.0 72.41 168 2014-04-26-0903.gpx
2014-04-25 09:58:51 Running 2.29 19:05 8:20 7.21 305.0 30.64 158 2014-04-25-0958.gpx
2014-04-23 10:34:00 Running 2.26 19:20 8:34 7.01 297.0 30.00 156 2014-04-23-1034.gpx
2014-04-22 09:37:31 Running 3.37 27:50 8:16 7.26 448.0 42.82 165 2014-04-22-0937.gpx
2014-04-18 11:17:38 Running 3.69 36:17 9:50 6.11 485.0 88.98 154 2014-04-18-1117.gpx
2014-04-12 09:58:38 Running 10.01 1:37:08 9:42 6.19 1335.0 174.82 159 2014-04-12-0958.gpx
2014-04-10 10:34:00 Running 6.47 1:02:38 9:41 6.20 851.0 105.36 160 2014-04-10-1034.gpx
2014-04-09 14:55:00 Running 2.18 19:56 9:09 6.56 289.0 31.18 157 2014-04-09-1455.gpx
2014-04-08 10:45:18 Running 6.25 59:35 9:32 6.29 832.0 0.00 160 2014-04-08-1045.gpx
2014-04-05 11:52:15 Running 5.40 50:47 9:24 6.38 720.0 87.91 158 2014-04-05-1152.gpx
2014-04-04 15:54:51 Running 2.25 18:36 8:16 7.26 298.0 29.73 163 2014-04-04-1554.gpx
2014-04-03 10:49:07 Running 5.46 49:54 9:08 6.56 727.0 96.27 168 2014-04-03-1049.gpx
2014-04-01 10:49:52 Running 4.03 35:17 8:46 6.85 548.0 54.87 168 2014-04-01-1049.gpx
2014-03-31 10:18:49 Running 2.20 18:38 8:28 7.08 298.0 29.59 167 2014-03-31-1018.gpx
2014-03-24 10:11:22 Running 3.27 27:30 8:24 7.14 433.0 39.71 171 2014-03-24-1011.gpx
2014-03-22 19:24:08 Running 0.74 6:31 8:51 6.78 97.0 9.18 157 2014-03-22-1924.gpx
2014-03-21 12:13:11 Running 3.01 27:18 9:04 6.62 400.0 39.82 168 2014-03-21-1213.gpx
2014-03-20 11:52:41 Running 2.06 17:02 8:17 7.25 272.0 30.45 171 2014-03-20-1152.gpx
2014-03-14 15:59:15 Running 2.11 19:17 9:09 6.56 279.0 31.66 164 2014-03-14-1559.gpx
2014-03-12 12:40:47 Running 2.11 19:00 9:01 6.66 284.0 32.55 171 2014-03-12-1240.gpx
2014-03-11 16:35:08 Running 2.10 19:21 9:13 6.51 278.0 30.73 168 2014-03-11-1635.gpx
2014-02-02 15:55:28 Running 1.15 9:26 8:13 7.31 154.0 12.33 161 2014-02-02-1555.gpx
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
/*
* value accessor - returns the value to encode for a given data object.
* scale - maps value to a visual display encoding, such as a pixel position.
* map function - maps from data value to display value
* axis - sets up axis
*/
// Setup x-axis (Distance)
var xValue = function(d) { return d["Distance (mi)"]; }, // data -> value
xScale = d3.scale.linear().range([0, width]), // value -> display
xMap = function(d) { return xScale(xValue(d)); }, // data -> display
xAxis = d3.svg.axis().scale(xScale).orient("bottom");
// Setup y-axis (Speed)
var yValue = function(d) { return d["Average Speed (mph)"]; }, // data -> value
yScale = d3.scale.linear().range([height, 0]), // value -> display
yMap = function(d) { return yScale(yValue(d)); }, // data -> display
yAxis = d3.svg.axis().scale(yScale).orient("left");
// Setup color as third dimension (date)
var color = d3.time.scale()
.domain([
new Date(2014,1,1),
new Date(2014,2,1),
new Date(2014,3,1),
new Date(2014,4,1),
new Date(2014,5,1)
])
.range(["red", "orange", "yellow", "green", "blue"])
.interpolate(d3.interpolateLab);
// Add the graph canvas to the webpage body
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Add the tooltip area to the webpage
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// Load data
d3.csv("cardioActivities.csv", function(error, data) {
// Change string (from CSV) into type number
data.forEach(function(d) {
// Distance
d["Distance (mi)"] = +d["Distance (mi)"];
// Speed
d["Average Speed (mph)"] = +d["Average Speed (mph)"];
// Date
d.date = d["Date"]; // <-- text for tooltip
d["Date"] = parseDate(d["Date"]); // <-- date value for color-coding
});
// don't want dots overlapping axis, so add in buffer to data domain
xScale.domain([d3.min(data, xValue)-0.2, d3.max(data, xValue)+1]);
yScale.domain([d3.min(data, yValue)-0.2, d3.max(data, yValue)+0.2]);
// x-axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.text("Distance (mi)");
// y-axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("class", "label")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Average Speed (mph)");
// draw dots
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 10)
.attr("cx", xMap)
.attr("cy", yMap)
.style("fill", function(d) { return color( +d['Date'] ); })
.on("mouseover", function(d) {
tooltip.transition()
.duration(200)
.style("opacity", .9);
tooltip.html(d.date + "<br/>" +
d['Distance (mi)'] + " miles @ " + d["Average Pace"] + "/mi")
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
// draw legend
var legend = svg.selectAll(".legend")
.data(color.domain())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) {
return "translate(0," + ((height / 2 - 100) + (i * 40)) + ")";
});
// draw legend colored rectangles
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
// draw legend text
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d.toLocaleDateString();})
});
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style>
body {
font: 12px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.dot {
stroke: #000;
}
.tooltip {
position: absolute;
width: 200px;
height: 28px;
pointer-events: none;
background-color: white;
font-size: 1.2em;
}
.legend {
font-size: 1.2em;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="cardioPlot.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment