Skip to content

Instantly share code, notes, and snippets.

@rwieruch
Created December 31, 2014 13:14
Show Gist options
  • Save rwieruch/1e1ee13299db48252e2c to your computer and use it in GitHub Desktop.
Save rwieruch/1e1ee13299db48252e2c to your computer and use it in GitHub Desktop.
Apple Health Bar 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
<!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;
}
.date-line {
fill: none;
stroke: #fff;
stroke-opacity: .6;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.bar {
fill: #fff;
fill-opacity: .3;
}
.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.scale.ordinal().rangeRoundBands([0, width], .4);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.tickFormat(d3.time.format("%b"))
.orient("bottom")
.ticks(50);
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(data.map(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: "#4291FA"},
{offset: "100%", color: "#03409B"}
])
.enter().append("stop")
.attr("offset", function(d) { return d.offset; })
.attr("stop-color", function(d) { return d.color; });
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.date); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.rate); })
.attr("rx", 5)
.attr("ry", 5)
.attr("height", function(d) { return height - y(d.rate); });
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: 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-down"; }))
.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