Skip to content

Instantly share code, notes, and snippets.

@cartoda
Last active February 2, 2017 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cartoda/7a5cbd2f6193e7f73b41 to your computer and use it in GitHub Desktop.
Save cartoda/7a5cbd2f6193e7f73b41 to your computer and use it in GitHub Desktop.
jQuery plugin for wayfinding

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

<!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