Visualing changes in Opening and Closing hours for Felix
Last active
January 1, 2020 08:36
-
-
Save tlfrd/53e397ccbfb30f18933856b741f04e94 to your computer and use it in GitHub Desktop.
Opening Hours
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit | |
height: 920 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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