Skip to content

Commit

Permalink
Incremental improvements and other WIP features
Browse files Browse the repository at this point in the history
* Toggling of states and styles
* Blurring map when viewing stats
* Computing statistics
* Rendering chart with ChartJS and canvas
  • Loading branch information
gobbledygook88 committed Dec 2, 2017
1 parent b73370a commit 7656636
Show file tree
Hide file tree
Showing 3 changed files with 237 additions and 56 deletions.
9 changes: 8 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,19 @@

<div id="stats-container">
<h3>Stats</h3>
<div class="canvas-container">
<canvas id="line-canvas"></canvas>
</div>
<div class="canvas-container">
<canvas id="zone-canvas"></canvas>
</div>
</div>

<script src="scripts/svg-pan-zoom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<script src="scripts/main.js"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-24583920-5"></script>
<script>
<script async>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
Expand Down
274 changes: 219 additions & 55 deletions scripts/main.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,53 @@
var ajax = new XMLHttpRequest();
var _total;

ajax.open("GET", "tubemap.svg", true);
ajax.send();
ajax.onload = function(e) {
var div = document.createElement("div");
div.setAttribute("id", "map-container");
div.innerHTML = ajax.responseText;
document.body.insertBefore(div, document.body.childNodes[0]);

hideText();
_total = displayTotal();

var svg = svgPanZoom('#status-map', {
center: true,
fit: true,
mouseWheelZoomEnabled: true,
panEnabled: true,
zoomEnabled: true
});

// Set initial zoom level
svg.zoomBy(2);
var _svg;
var _svgEl;
var _stations;

function loadSVG() {
var ajax = new XMLHttpRequest();
ajax.open("GET", "tubemap.svg", true);
ajax.send();
ajax.onload = function(e) {
var div = document.createElement("div");
div.setAttribute("id", "map-container");
div.innerHTML = ajax.responseText;
document.body.insertBefore(div, document.body.childNodes[0]);

hideText();
_total = displayTotal();

_svgEl = document.getElementById("status-map");

_svg = svgPanZoom('#status-map', {
center: true,
fit: true,
mouseWheelZoomEnabled: true,
panEnabled: true,
zoomEnabled: true
});

// Set initial zoom level
_svg.zoomBy(2);
}
}
loadSVG();

function loadStations() {
var ajax = new XMLHttpRequest();
ajax.open("GET", "stations.json", true);
ajax.send();
ajax.onreadystatechange = function() {
if(ajax.readyState === 4) {
if(ajax.status === 200) {
_stations = JSON.parse(ajax.responseText);
}
}
}
}
loadStations();

var _s = {};
var _correct = {};
var _manualFixes = {
// Parsed text: Correct text
"bromley bybow": "bromley by bow",
Expand Down Expand Up @@ -79,9 +102,9 @@ function show(name) {

function normalise(name) {
return name.toLowerCase()
.replace(/[^\w\s]/gi, "") // Remove punctuation
.replace(/ and /gi, " ") // Remove 'and'. Note: two spaces
.trim();
.replace(/[^\w\s]/gi, "") // Remove punctuation
.replace(/ and /gi, " ") // Remove 'and'. Note: two spaces
.trim();
}

var current = document.getElementById("current");
Expand Down Expand Up @@ -109,6 +132,48 @@ function add() {
timer.textContent = pad(hours) + ":" + pad(minutes) + ":" + pad(seconds);
}

function inView(elDims, vbDims) {
return (
elDims.bottom <= vbDims.bottom &&
elDims.left >= vbDims.left &&
elDims.right <= vbDims.right &&
elDims.top >= vbDims.top
);
}

function panIntoView(elDims, vbDims) {
// Compute how much we need to move by
console.log(elDims);
var inv = _svgEl.getScreenCTM().inverse();
// Transform element position into SVG coordinates
var svgTop = _svgEl.createSVGPoint();
svgTop.x = elDims.top;
svgTop.y = elDims.left;
var svgTopP = svgTop.matrixTransform(inv);
console.log(inv, svgTopP);

// Find which direction to move in
var h; // 1 is left, -1 is right
var v; // 1 is down, -1 is up

// _svg.pan({x: elDims.x, y: elDims.y});
_svg.panBy({x: 0, y: -300});
}


function isVisible(name) {
// Since the svg is 'full-screen', we take the body rectangle as the viewbox
var vbDims = document.body.getBoundingClientRect();

_s[name].forEach(function(el) {
var elDims = el.getBoundingClientRect();
if(!inView(elDims, vbDims)) {
console.log(el);
panIntoView(elDims, vbDims);
}
});
}

var started = false;
var t;

Expand All @@ -121,13 +186,29 @@ document.getElementById("guess").addEventListener("input", function(e) {

var guess = normalise(this.value);

// Check if guess has already been guessed
if(_correct[guess]) {
console.log("Already guessed");
}

// Check if guess is correct
if(_s[guess]) {
show(guess);

// Check if station name is fully in view (may not be due to pan and zoom)
isVisible(guess);

// Pan to station name if necessary

// Reset input field
this.value = "";

// Remove
// Remove DOM references
delete _s[guess];

// Add to correct guesses
_correct[guess] = true; // TODO copy lines and zones

// Increment counter and update
counter++;
current.innerHTML = counter;
Expand All @@ -139,15 +220,82 @@ document.getElementById("guess").addEventListener("input", function(e) {
}
});

function blur(el) {
el.style.filter = "blur(3px)";
el.style.opacity = 0.2;
}

function unblur(el) {
el.style.filter = "none";
el.style.opacity = 1;
}

function enableSVGPanZoom() {
_svg.enablePan();
_svg.enableZoom();
}

function disableSVGPanZoom() {
_svg.disablePan();
_svg.disableZoom();
}

var color = Chart.helpers.color;
var lineStatsData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: 'Dataset 1',
backgroundColor: color("#FF0000").alpha(0.5).rgbString(),
borderColor: "#FF0000",
borderWidth: 1,
data: [10, 20, 30, 40, 50, 60, 70]
}]
};

function createDataArray(keys, obj, key) {
let values = [];
for(let k of keys) {
values.push(obj[k][key]);
}

return values;
}

function updateStats() {
// Calculate per line statistics
let lineStats = {};
for(const [line, stations] of Object.entries(_stations.lines)) {
let normalisedStations = stations.map(normalise);

let correct = 0;
for(let s of Object.keys(_correct)) {
if(normalisedStations.includes(s)) {
correct++;
}
}
lineStats[line] = {
total: stations.length,
correct: correct,
percentage: Number((correct / stations.length * 100).toFixed(2))
};
}
lineStatsData.labels = Object.keys(lineStats).sort();
lineStatsData.datasets[0].data = createDataArray(lineStatsData.labels, lineStats, "percentage");
window.lineStatsChart.update();

// Calculate per zone statistics
}

document.getElementById("pause").addEventListener("click", function(e) {
// Stop the timer
clearInterval(t);

// Hide map
document.getElementById("map-container").style.display = "none";
blur(document.getElementById("map-container"));
disableSVGPanZoom();

// Show stats
document.getElementById("stats-container").style.display = "visible";
document.getElementById("stats-container").style.display = "block";
updateStats();

e.preventDefault();
});
Expand All @@ -159,32 +307,48 @@ document.getElementById("resume").addEventListener("click", function(e) {
// Hide stats
document.getElementById("stats-container").style.display = "none";

// Show map
document.getElementById("map-container").style.display = "visible";
unblur(document.getElementById("map-container"));
enableSVGPanZoom();

e.preventDefault();
});

/*
Stop/Pause button
- stops the clock and switches to stats view
Statistics
{
"time_spent": 0,
"stations_total": 0,
"stations_correct": 0,
"lines": {
"Bakerloo": 0
},
"zones": {
"Zone 1": 0,
"Zone 2": 0
}
}
Lines breakdown: abstract line chart with percentages
Zones breakdown: abstract zone map with percentages
Show averages
*/
window.onload = function() {
var ctx = document.getElementById("line-canvas").getContext("2d");
window.lineStatsChart = new Chart(ctx, {
type: 'horizontalBar',
data: lineStatsData,
options: {
elements: {
rectangle: {
borderWidth: 2,
}
},
responsive: true,
legend: {
display: false
},
title: {
display: false,
text: 'By line'
},
scales: {
xAxes: [{
ticks: {
beginAtZero: true,
min: 0,
max: 100
}
}],
yAxes: [{
ticks: {
mirror: false
}
}]
},
tooltips: {
enabled: false
}
}
});
};
10 changes: 10 additions & 0 deletions styles/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,15 @@ svg {
}

#stats-container {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
display: none;
}

.canvas-container {
position: relative;
width: 50%;
}

0 comments on commit 7656636

Please sign in to comment.