Skip to content

Instantly share code, notes, and snippets.

@mayo
Forked from mbostock/weekday.js
Last active July 16, 2016 04:32
Show Gist options
  • Save mayo/c0c1ca7f5bbb30cc3ef3 to your computer and use it in GitHub Desktop.
Save mayo/c0c1ca7f5bbb30cc3ef3 to your computer and use it in GitHub Desktop.
Weekdays

A basic example of using mbostock's weekday.js gist to to plot only weekdays using a linear scale. The resulting charts will not show gaps where weekends would be.

date value
01/5/2014 1
02/5/2014 2
05/5/2014 1
06/5/2014 2
08/5/2014 2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="weekday.js"></script>
<title>Scale test</title>
<style>
body {
font-family: 'helvetica neue';
font-size: .8em;
}
.line {
fill: none;
stroke: black;
stroke-width: 1px;
}
.axis line,
.axis path {
stroke-width: 1px;
stroke: black;
fill: none;
}
.dots circle {
fill: #555;
fill-opacity: .5;
}
</style>
</head>
<body>
<div id="chart"></div>
<script>
var margin = {top: 20, right: 50, bottom: 50, left: 20},
width = 960 - margin.left - margin.right,
height = 502 - margin.top - margin.bottom;
var parseDate = d3.time.format("%d/%m/%Y").parse;
var dayCount = 0;
var x = d3.scale.linear()
.range([0, width - margin.right]);
var y = d3.scale.linear()
.range([0, height - margin.left]);
var dateFormat = d3.time.format('%a %b %d');
var xAxis = d3.svg.axis()
.scale(x)
.orient("below")
.tickFormat(function (d) { return dateFormat(weekday.invert(d)); });
var yAxis = d3.svg.axis()
.scale(y)
.orient("right");
var line = d3.svg.line()
.x(function(d) { return x(d.weekday); })
.y(function(d) { return y(d.value); });
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
d3.csv("data.csv", type, function(error, data) {
x.domain(d3.extent(data, function(d) { return d.weekday; }));
y.domain(d3.extent(data, function(d) { return parseFloat(d.value); }))
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("d", line);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + margin.left + "," + (margin.top + height + 20) + ")")
.call(xAxis)
.selectAll("text")
.attr("dy", ".35em");
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + (width + 20) + "," + margin.top + ")")
.call(yAxis)
.selectAll("text")
.attr("dy", ".35em");
svg.append("g")
.attr("class", "dots")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("r", 5)
.attr("cx", function(d) { return x(d.weekday); })
.attr("cy", function(d) { return y(d.value); });;
});
function type(d) {
d.date = parseDate(d.date);
d.weekday = weekday(d.date);
return d
}
</script>
</body>
</html>
// This function originated from mbostock's gist: https://gist.github.com/mbostock/5827353
weekday = (function() {
// Returns the weekday number for the given date relative to January 1, 1970.
function weekday(date) {
var weekdays = weekdayOfYear(date),
year = date.getFullYear();
while (--year >= 1970) weekdays += weekdaysInYear(year);
return weekdays;
}
// Returns the date for the specified weekday number relative to January 1, 1970.
weekday.invert = function(weekdays) {
var year = 1970,
yearWeekdays;
// Compute the year.
while ((yearWeekdays = weekdaysInYear(year)) <= weekdays) {
++year;
weekdays -= yearWeekdays;
}
// Compute the date from the remaining weekdays.
var days = weekdays % 5,
day0 = ((new Date(year, 0, 1)).getDay() + 6) % 7;
if (day0 + days > 4) days += 2;
return new Date(year, 0, (weekdays / 5 | 0) * 7 + days + 1);
};
// Returns the number of weekdays in the specified year.
function weekdaysInYear(year) {
return weekdayOfYear(new Date(year, 11, 31)) + 1;
}
// Returns the weekday number for the given date relative to the start of the year.
function weekdayOfYear(date) {
var days = d3.time.dayOfYear(date),
weeks = days / 7 | 0,
day0 = (d3.time.year(date).getDay() + 6) % 7,
day1 = day0 + days - weeks * 7;
return Math.max(0, days - weeks * 2
- (day0 <= 5 && day1 >= 5 || day0 <= 12 && day1 >= 12) // extra saturday
- (day0 <= 6 && day1 >= 6 || day0 <= 13 && day1 >= 13)); // extra sunday
}
return weekday;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment