Skip to content

Instantly share code, notes, and snippets.

@rwieruch
Last active October 16, 2022 16:32
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rwieruch/7b90f99823ee1feda28a to your computer and use it in GitHub Desktop.
Save rwieruch/7b90f99823ee1feda28a to your computer and use it in GitHub Desktop.
Apple Health Line Chart
date rate
1-Jan-15 210.73
1-Dec-14 196.97
1-Nov-14 189.31
1-Oct-14 180.86
1-Sep-14 165.30
1-Aug-14 166.43
1-Jul-14 142.83
1-Jun-14 139.35
1-May-14 127.24
1-Apr-14 108.69
1-Mar-14 123.94
1-Feb-14 155.51
1-Jan-14 128.35
1-Dec-13 120.93
1-Nov-13 106.96
1-Oct-13 109.12
1-Sep-13 166.19
1-Aug-13 156.66
1-Jul-13 174.68
1-Jun-13 186.10
1-May-13 180.00
1-Apr-13 149.53
1-Mar-13 121.73
1-Feb-13 133.75
1-Jan-13 194.84
1-Dec-12 178.86
1-Nov-12 187.44
1-Oct-12 156.34
1-Sep-12 144.16
1-Aug-12 135.00
1-Jul-12 121.26
1-Jun-12 118.40
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 12px sans-serif;
}
.background {
fill: url(#background-gradient);
shape-rendering: geometricPrecision;
}
.axis path,
.axis line {
display: none;
}
.tick text {
fill: #fff;
}
.line {
fill: none;
stroke: #fff;
stroke-width: 1.5px;
}
.date-line {
fill: none;
stroke: #fff;
stroke-opacity: .6;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.area {
fill: url(#area-gradient);
}
.dot {
stroke: #fff;
fill: #FF4330;
stroke-width: 1.5px;
}
.label-small {
fill: #fff;
fill-opacity: 1;
font-size: 12px;
}
.label-large {
fill: #fff;
fill-opacity: 1;
font-size: 16px;
}
.icon {
fill: #fff;
stroke: #fff;
stroke-width: 1.5px;
shape-rendering: geometricPrecision;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.js"></script>
<script>
var margin = {top: 60, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;
var parseDate = d3.time.format("%d-%b-%y").parse;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var line = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.rate); });
var area = d3.svg.area()
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.rate); });
var svg = d3.select("body").append("svg")
.attr("class", "svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.append("rect")
.attr("class", "background")
.attr("rx", "5px")
.attr("ry", "5px")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.tsv("data.tsv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.rate = +d.rate;
});
var maxValue = d3.max(data, function(d) { return d.rate; }) + 20,
minValue = d3.min(data, function(d) { return d.rate; }) - 20;
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([minValue, maxValue]);
svg.append("linearGradient")
.attr("id", "background-gradient")
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", 0).attr("y1", 0)
.attr("x2", 0).attr("y2", height)
.selectAll("stop")
.data([
{offset: "0%", color: "#FF9250"},
{offset: "100%", color: "#FF4330"}
])
.enter().append("stop")
.attr("offset", function(d) { return d.offset; })
.attr("stop-color", function(d) { return d.color; });
svg.append("linearGradient")
.attr("id", "area-gradient")
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", 0).attr("y1", y(0))
.attr("x2", 0).attr("y2", y(d3.max(data, function(d) { return d.rate; })))
.selectAll("stop")
.data([
{offset: "40%", color: "#fff", opacity: "0%"},
{offset: "100%", color: "#fff", opacity: "30%"}
])
.enter().append("stop")
.attr("offset", function(d) { return d.offset; })
.attr("stop-color", function(d) { return d.color; })
.attr("stop-opacity", function(d) { return d.opacity; });
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + (-15) + "," + height + ")")
.call(xAxis);
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
svg.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area);
svg.append("g").attr("class", "scatter")
.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("cx", function(d) {
return x(d.date);
})
.attr("cy", function(d) {
return y(d.rate);
})
.attr("r", 3);
svg.append("g").selectAll("line")
.data([
{y1: y(minValue), y2: y(minValue), x1: 0, x2: width},
{y1: y((maxValue+minValue)/2), y2: y((maxValue+minValue)/2), x1: 0, x2: width},
{y1: y(maxValue), y2: y(maxValue), x1: 0, x2: width},
])
.enter().append("line")
.attr("class", "date-line")
.attr("y1", function(d) { return d.y1; })
.attr("y2", function(d) { return d.y2; })
.attr("x1", function(d) { return d.x1; })
.attr("x2", function(d) { return d.x2; });
svg.append("g").selectAll("text")
.data([
{text: d3.round(minValue, 0), x: width, y: y(minValue) - 5, anchor: "end", labelClass: "label-small"},
{text: d3.round(maxValue, 0), x: width, y: y(maxValue) + 15, anchor: "end", labelClass: "label-small"},
{text: "Daily Avg: " + d3.round(d3.mean(data ,function (d) { return d.rate}), 0), x: 50, y: y(maxValue) - 5, anchor: "start", labelClass: "label-small"},
{text: "Calories Burned", x: 50, y: y(maxValue) - 25, anchor: "start", labelClass: "label-large"},
{text: d3.round(data[0].rate, 0) + "cal", x: width, y: y(maxValue) - 25, anchor: "end", labelClass: "label-large"},
{text: "Today", x: width, y: y(maxValue) - 5, anchor: "end", labelClass: "label-small"}
])
.enter().append("text")
.attr("class", function(d) { return d.labelClass; })
.text(function(d) { return d.text; })
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("text-anchor", function(d) { return d.anchor; });
svg.append("path")
.attr("d", d3.svg.symbol()
.size(function(d) { return 400; })
.type(function(d) { return "triangle-up"; }))
.attr("class", "icon")
.attr("transform", "translate(" + 25 + "," + (-20) + ")");
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment