Visualing changes in Opening and Closing hours for Felix
xxxxxxxxxx
<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>
https://d3js.org/d3.v4.min.js