This example shows how to build a simple digital wayfinding service using the jQuery wayfinding plugin. The plugin has been customized to permit the correct interaction with the zoom environment provided by the D3.js library
Last active
February 2, 2017 14:21
-
-
Save cartoda/7a5cbd2f6193e7f73b41 to your computer and use it in GitHub Desktop.
jQuery plugin for wayfinding
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> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<title>wayfinding</title> | |
<meta name="description" content=""> | |
<meta name="viewport" content="width=device-width"> | |
<link rel="stylesheet" href="http://wafi.iit.cnr.it/webvis/tmp/wayfinding/styles/example.css"> | |
<style> | |
.custom-menu { | |
display: none; | |
z-index: 1000; | |
position: absolute; | |
overflow: hidden; | |
border: 1px solid #CCC; | |
white-space: nowrap; | |
font-family: sans-serif; | |
background: #FFF; | |
color: #333; | |
border-radius: 5px; | |
padding: 0; | |
} | |
/* Each of the items in the list */ | |
.custom-menu li { | |
padding: 8px 12px; | |
cursor: pointer; | |
list-style-type: none; | |
} | |
.custom-menu li:hover { | |
background-color: #DEF; | |
} | |
</style> | |
</head> | |
<body style="font-size: 10pt"> | |
<ul class='custom-menu'> | |
<li data-action="source">Imposta come sorgente</li> | |
<li data-action="sink">Imposta come destinazione</li> | |
</ul> | |
<div id="content"> | |
<div id="mapLoading">Loading</div> | |
<div id="myMaps"> | |
</div> | |
<div id="controls"> | |
<label for="beginSelect">Begin Route at</label> | |
<select id="beginSelect"> | |
<option value="Entrance">Entrance</option> | |
<option value="A1">A1</option> | |
<option value="A2">A2</option> | |
<option value="A3">A3</option> | |
<option value="A4">A4</option> | |
<option value="A5">A5</option> | |
<option value="A6">A6</option> | |
<option value="A7">A7</option> | |
<option value="A8">A8</option> | |
<option value="A9">A9</option> | |
<option value="A10">A10</option> | |
<option value="A11">A11</option> | |
<option value="A12">A12</option> | |
<option value="A13">A13</option> | |
<option value="A14">A14</option> | |
<option value="A15">A15</option> | |
<option value="A16">A16</option> | |
</select> | |
<label for="endSelect">Show Route to</label> | |
<select id="endSelect"> | |
<option value="Entrance">Entrance</option> | |
<option value="A1" selected>A1</option> | |
<option value="A2">A2</option> | |
<option value="A3">A3</option> | |
<option value="A4">A4</option> | |
<option value="A5">A5</option> | |
<option value="A6">A6</option> | |
<option value="A7">A7</option> | |
<option value="A8">A8</option> | |
<option value="A9">A9</option> | |
<option value="A10">A10</option> | |
<option value="A11">A11</option> | |
<option value="A12">A12</option> | |
<option value="A13">A13</option> | |
<option value="A14">A14</option> | |
<option value="A15">A15</option> | |
<option value="A16">A16</option> | |
</select> | |
<!-- | |
<label for="accessible">Accessible</label> | |
<input id="accessible" type="checkbox" name="accessible" value="Accessible" /> | |
--> | |
</div> | |
</div> | |
<div> | |
<ul> | |
<li>Choose the source/destination using the correspondent drop-down menus. You ca also:</li> | |
<ul> | |
<li>Click with the left button of the mouse to choose the correspondent room as destination</li> | |
<li>Click with the right button of the mouse to choose if the correspondent room must be setted as source or destination</li> | |
<li>Zoom on the maps</li> | |
</ul> | |
</ul> | |
</div> | |
<script src="http://code.jquery.com/jquery-1.11.1.js"></script> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="http://wafi.iit.cnr.it/webvis/tmp/wayfinding/scripts/jquery.wayfinding.js"></script> | |
<script> | |
// Variables for wayfinding | |
var MAPS = [ | |
{'path': 'http://wafi.iit.cnr.it/webvis/tmp/wayfinding/floor1.svg', 'id': 'floor1'}, | |
{'path': 'http://wafi.iit.cnr.it/webvis/tmp/wayfinding/floor2.svg', 'id': 'floor2'} | |
]; | |
var START_ROOM = 'Entrance'; | |
var DEFAULT_MAP = 'floor1'; | |
var lastRoomSelected; | |
// Variables for zoom | |
var MAX_ZOOM_IN = 16.0; | |
var MAX_ZOOM_OUT = 1.0; | |
var zoomScaleStep = 2; | |
var zoomTranslationMap = d3.map(); | |
var translationStep = 100; | |
var zoomable_layer, zoom; | |
var zoomObjects = []; | |
zoomTranslationMap.set(1, 0.0); | |
zoomTranslationMap.set(2, 1.0); | |
zoomTranslationMap.set(4, 3.0); | |
zoomTranslationMap.set(8, 2.33); | |
zoomTranslationMap.set(16, 2.14); | |
//Setup options for wayfinding | |
$(document).ready(function () { | |
'use strict'; | |
$('#myMaps').wayfinding({ | |
'maps': MAPS, | |
'path': { | |
width: 3, | |
color: 'cyan', | |
radius: 8, | |
speed: 8 | |
}, | |
'startpoint': function () { | |
return START_ROOM; | |
}, | |
'defaultMap': DEFAULT_MAP | |
}); | |
//Make the floor buttons clickable | |
$("#controls button").click(function () { | |
$("#myMaps").wayfinding('currentMap',$(this).attr('id')); | |
}); | |
$('#controls #beginSelect').change(function () { | |
$('#myMaps').wayfinding('startpoint', $(this).val()); | |
if ($('#controls .endSelect').val() !== '') { | |
$('#myMaps').wayfinding('routeTo', $('#controls #endSelect').val()); | |
} | |
}); | |
$('#controls #endSelect').change(function () { | |
$('#myMaps').wayfinding('routeTo', $(this).val()); | |
}); | |
$('#controls #accessible').change(function () { | |
if ($('#controls #accessible:checked').val() !== undefined) { | |
$('#myMaps').wayfinding('accessibleRoute', true); | |
} else { | |
$('#myMaps').wayfinding('accessibleRoute', false); | |
} | |
$('#myMaps').wayfinding('routeTo', $('#controls #endSelect').val()); | |
}); | |
setZoomEnvironment(); | |
}); | |
//Create the zoom beaviour and wait for map creation and then set zoom behaviour on it | |
function setZoomEnvironment(){ | |
//Create the zoom behavior to set for the draw | |
zoom = d3.behavior.zoom().scaleExtent([MAX_ZOOM_OUT, MAX_ZOOM_IN]).on('zoom', zoomed); | |
//Wait for the creation of all maps | |
waitMapsCreation(); | |
} | |
function waitMapsCreation(){ | |
var checkMapsCreationFunction = setInterval(function() { | |
var allMapsCreated = true; | |
$.map(MAPS, function(value) { | |
if($('#' + value.id).length == 0){ | |
allMapsCreated = false; | |
} | |
}); | |
if(allMapsCreated){ | |
//Cancel the timer | |
clearInterval(checkMapsCreationFunction); | |
//Create the zoom environment | |
$.map(MAPS, function(value) { | |
setZoomBehaviourForMap(value.id); | |
}); | |
//Update the destination in the drop-down menu when the correspondent room is clicked and create the custom context menu | |
$('#Rooms a') | |
.on('click', function () { | |
$('#controls #endSelect option[value="' + $(this).prop('id') + '"]').attr('selected', true); | |
}) | |
.on('contextmenu', function (event) { | |
// Avoid the real one | |
event.preventDefault(); | |
//Set the last room selected | |
lastRoomSelected = $(this).prop('id'); | |
// Show contextmenu | |
$(".custom-menu").finish().toggle(100). | |
// In the right position (the mouse) | |
css({ | |
top: event.pageY + "px", | |
left: event.pageX + "px" | |
}); | |
}) | |
.on("mousedown", function (e) { | |
// If the clicked element is not the menu | |
if (!$(e.target).parents(".custom-menu").length > 0) { | |
// Hide it | |
$(".custom-menu").hide(100); | |
} | |
}); | |
//Set the actions to do on the option selection in the context menu | |
$(".custom-menu li").click(function(){ | |
// This is the triggered action name | |
switch($(this).attr("data-action")) { | |
// A case for each action. Your actions here | |
case "source": | |
$('#controls #beginSelect option[value="' + lastRoomSelected + '"]').attr('selected', true); | |
$('#controls #beginSelect').trigger("change"); | |
break; | |
case "sink": | |
$('#controls #endSelect option[value="' + lastRoomSelected + '"]').attr('selected', true); | |
$('#controls #endSelect').trigger("change"); | |
break; | |
} | |
// Hide it AFTER the action was triggered | |
$(".custom-menu").hide(100); | |
}); | |
} | |
}, 100); // check every 100ms | |
} | |
function setZoomBehaviourForMap(mapId){ | |
//Create specific variables for map zooming | |
var mapObj = d3.select('#' + mapId + " svg").call(zoom); | |
var zoomMap = mapObj.select("g"); | |
var svgWidth = mapObj.attr('width').replace('px', ''); | |
var svgHeight = mapObj.attr('height').replace('px', ''); | |
var centerX = d3.round(-(svgWidth / 2)); | |
var centerY = d3.round(-(svgHeight / 2)); | |
zoomObjects[mapId] = { | |
zoomMap: zoomMap, | |
svgWidth: svgWidth, | |
svgHeight: svgHeight, | |
centerX: centerX, | |
centerY: centerY | |
}; | |
//Set the zoom behavior on the floor | |
//zoomMap.call(zoom); | |
} | |
//Function called on the zoom event. It translate the draw on the zoommed point and scale with a certain factor | |
function zoomed() { | |
var id = d3.select(this.parentNode).attr("id"); | |
var zoomObj = zoomObjects[id]; | |
zoomObj.centerX = d3.round(d3.event.translate[0]); | |
zoomObj.centerY = d3.round(d3.event.translate[1]); | |
//alert("Richiesto livello di zoom " + d3.event.scale + " e traslazione in " + centerX + ", " + centerY); | |
zoomObj.zoomMap.attr("transform", "translate(" + zoomObj.centerX + ", " + zoomObj.centerY + ")scale(" + d3.event.scale + ")"); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment