Skip to content

Instantly share code, notes, and snippets.

@tlfrd
Last active January 1, 2020 08:36
Show Gist options
  • Save tlfrd/53e397ccbfb30f18933856b741f04e94 to your computer and use it in GitHub Desktop.
Save tlfrd/53e397ccbfb30f18933856b741f04e94 to your computer and use it in GitHub Desktop.
Opening Hours
license: mit
height: 920

Visualing changes in Opening and Closing hours for Felix

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400, 600" rel="stylesheet">
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
text {
font-family: 'Open Sans', sans-serif;
}
.bar-label {
fill: white;
}
.old-hours {
fill: #2c7fb8;
stroke: white;
}
.new-hours {
fill: #253494;
stroke: white;
}
.x-axis text {
font-size: 14px;
}
.grid-line {
stroke: black;
opacity: 0.2;
stroke-dasharray: 5,5;
}
.title {
font-size: 20px;
}
</style>
</head>
<body>
<script>
var margin = {top: 100, right: 100, bottom: 100, left: 100};
var width = 960,
height = 1000;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var parseTime = d3.timeParse("%H:%M");
var formatTime = d3.timeFormat("%H:%M");
d3.queue()
.defer(d3.csv, "opening-hours.csv")
.defer(d3.csv, "opening-term-hours.csv")
.await(load);
function load(error, hours, termHours) {
if (error) throw error;
var config1 = {
width: width - margin.left - margin.right,
height: (height / 2) - margin.top - margin.bottom
};
var config2 = {
width: width - margin.left - margin.right,
height: (height / 2.4) - margin.top - margin.bottom
}
var arr1 = ["Out of Term Hours Old Open","Out of Term Hours Old Close","Out of Term Hours New Open","Out of Term Hours New Close"];
var elem1 = svg.append("g")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
drawChart(elem1, config1, hours, arr1, "Out Of Term Hours");
var arr2 = ["Opening Term Hours Old","Closing Term Hours Old","Opening Term Hours New","Closing Term Hours New"];
var elem2 = svg.append("g")
.attr("transform", "translate(" + [margin.left, margin.top + height / 2] + ")")
drawChart(elem2, config2, termHours, arr2, "Term Hours");
}
function drawChart(elem, config, data, selectors, label) {
var places = d3.scaleBand()
.range([0, config.height])
.padding(0.1);
places.domain(data.map(d => d["Outlet Name"]));
var time = d3.scaleTime()
.domain([parseTime("06:00"), parseTime("24:00")])
.range([0, config.width]);
data.forEach(function(place) {
for (var attribute in place) {
if (attribute != "Outlet Name") {
place[attribute] = parseTime(place[attribute]);
}
}
});
var title = elem.append("text")
.attr("class", "title")
.attr("y", -margin.top / 3)
.text(label)
var xAxis = d3.axisBottom(time)
.tickFormat((d, i) => i % 2 == 0 ? formatTime(d) : "")
.ticks(24);
var xGroup = elem.append("g");
var xAxisElem = xGroup.append("g")
.attr("transform", "translate(" + [0, config.height + margin.bottom / 4] + ")")
.attr("class", "x-axis")
.call(xAxis);
var grid = xGroup.append("g").selectAll("line")
.data(time.ticks(24))
.enter().append("line")
.attr("class", "grid-line")
.attr("x1", d => time(d) + 0.5)
.attr("x2", d => time(d) + 0.5)
.attr("y1", -margin.bottom / 8)
.attr("y2", config.height + margin.bottom / 4);
var hourBars = elem.append("g")
.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", d => "translate(" + [0, places(d["Outlet Name"])] + ")")
.attr("class", "place-hours");
var oldHours = hourBars.append("rect")
.attr("class", "old-hours")
.attr("x", d => time(d[selectors[0]]))
.attr("width", d => time(d[selectors[1]]) - time(d[selectors[0]]))
.attr("height", places.bandwidth());
var newHours = hourBars.append("rect")
.attr("class", "new-hours")
.attr("x", d => time(d[selectors[2]]))
.attr("width", d => time(d[selectors[3]]) - time(d[selectors[2]]))
.attr("height", places.bandwidth());
var labels = hourBars.append("text")
.attr("class", "bar-label")
.attr("text-anchor", "middle")
.attr("x", d => time(d[selectors[2]]))
.attr("dx", d => (time(d[selectors[3]]) - time(d[selectors[2]])) / 2)
.attr("y", places.bandwidth() / 2)
.attr("dy", places.bandwidth() / 8)
.style("font-size", places.bandwidth() / 2)
.text(d => d["Outlet Name"]);
var legendOffsets = 100;
var legend = elem.append("g")
.attr("class", "legend")
.attr("transform", "translate(" + [config.width - margin.right / 2, -margin.top / 2] +")");
var legendElems = legend.selectAll("g")
.data([{class: "old-hours", label: "Old"}, {class: "new-hours", label: "New"}])
.enter().append("g")
.attr("transform", (d, i) => "translate(" + [-i * legendOffsets, 0] + ")")
legendElems.append("rect")
.attr("class", d => d.class)
.attr("width", places.bandwidth() / 2)
.attr("height", places.bandwidth() / 2)
legendElems.append("text")
.attr("x", places.bandwidth() / 2)
.attr("y", places.bandwidth() / 2)
.attr("dx", 10)
.attr("dy", -places.bandwidth() / 16)
.text(d => d.label);
}
</script>
</body>
Outlet Name Out of Term Hours Old Open Out of Term Hours Old Close Out of Term Hours New Open Out of Term Hours New Close Term Hours Old Term Hours Old Term Hours New Term Hours New
SCR Restaurant 08:00 19:00 08:00 17:00 08:00 19:00 08:00 18:00
SAF Café 08:30 16:00 09:00 16:00 08:30 17:30 09:00 16:00
Fuel 11:00 14:30 11:30 14:30 11:00 14:30 11:30 14:30
JCR QT Shop 08:00 16:00 10:00 16:00 08:00 18:00 10:00 16:00
JCR Deli Bar 11:00 14:30 11:30 14:30 11:00 14:30 11:30 14:30
Ethos (Weekday) 07:00 22:00 07:00 20:00
Ethos (Weekend) 08:00 20:00 08:00 16:00
Eastside (Mon-Thu) 12:00 23:00 12:00 21:00
Outlet Name Opening Term Hours Old Closing Term Hours Old Opening Term Hours New Closing Term Hours New
SCR Restaurant 08:00 19:00 08:00 18:00
SAF Café 08:30 17:30 09:00 16:00
Fuel 11:00 14:30 11:30 14:30
JCR QT Shop 08:00 18:00 10:00 16:00
JCR Deli Bar 11:00 14:30 11:30 14:30
Eastside (Mon-Thu) 12:00 23:00 12:00 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment