Skip to content

Instantly share code, notes, and snippets.

@DanielSitarz
Last active March 17, 2022 09:26
Show Gist options
  • Save DanielSitarz/a808daaa588d046abcf6a7a84357aabd to your computer and use it in GitHub Desktop.
Save DanielSitarz/a808daaa588d046abcf6a7a84357aabd to your computer and use it in GitHub Desktop.
<html>
<head>
<link rel="stylesheet" href="node_modules/@indoorway/map-js/dist/leaflet.css">
<link rel="stylesheet" href="node_modules/@indoorway/map-js/dist/map-js.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body, .map-container {
width: 100vw;
height: 100vh;
}
.date-pickers {
position: absolute;
left: 8px;
top: 8px;
z-index: 100;
}
</style>
</head>
<body>
<div class="map-container" id="map-container"></div>
<script type="module">
import MapJS from "./node_modules/@indoorway/map-js/dist/map-js.es2015.js";
const mapJS = new MapJS();
const API_ADDRESS = 'https://julki.indoorway.com/v1/graphql';
const WEB_API_TOKEN = 'cd433b4f-2916-4a3f-9143-31f62f24c57b'; // Demo account
const FILTERS = {
from: '2018-08-06T00:00:00.000Z',
to: '2018-08-12T23:59:59.999Z',
excludedAreaTypes: ['open_space']
}
makeAPICall(`{
mapsList {
uuid,
osm,
outline,
logotypeList {
thumb_url,
uuid
}
}
}`).then(function(jsonResponse) {
// Get first map from response
const mapData = jsonResponse.data.mapsList[0];
// Render map into HTML
const map = mapJS.render(mapData, {
container: document.getElementById('map-container'),
logotypes: mapData.logotypeList
});
processMap(map, mapData.uuid);
});
function processMap(map, mapUuid) {
const AREAS = map.layers.areas
.getLayers()
.filter((area) => !FILTERS.excludedAreaTypes.includes(area.feature.properties.indoorObjectType));
// Gather UUIDs of all areas in this location
const AREAS_UUIDS = AREAS.map((area) => area.feature.properties.indoorObjectId)
// Prepare requests for Visits Statistics for each area
const whenAreasVisistsStats = AREAS_UUIDS.map((areaUuid) => getAreaVisitsStats(mapUuid, areaUuid, FILTERS))
// Get all the data
Promise.all(whenAreasVisistsStats).then((areasVisitsStats) => {
// We got array of avg times for each day in time span we requested.
// Lets sum it and take an avg
const avgVisitTimes = areasVisitsStats.map((areaVisitStats, i) => {
const visitStats = areaVisitStats.data.map.analytics.room.visitsTimeStats;
const sum = visitStats.reduce((prev, current) => prev + current.avgTime, 0);
const avg = sum / visitStats.length;
return avg;
})
// Calc min and max value. Will be used to interpolate color later
const AVG_MIN = 0;
const AVG_MAX = Math.max(...avgVisitTimes);
// Colorize each area depending of their avg visit time
AREAS.forEach((area, i) => {
// We can do this, because returned values are in order of the Promises passed
const avgTime = avgVisitTimes[i];
const intensity = 255 * (avgTime / AVG_MAX);
area.setStyle({
fillColor: `rgba(0, ${intensity}, 0)`
})
})
})
}
function makeAPICall(query) {
return fetch(API_ADDRESS, {
method: 'POST',
headers: {
'WEB-API-TOKEN': WEB_API_TOKEN, // From dashboard's access section
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({ query: query })
}).then(function(response) {
return response.json();
})
}
function getAreaVisitsStats(mapUuid, areaUuid, filters) {
// Areas are named rooms on backend
return makeAPICall(`{
map (uuid: "${mapUuid}") {
analytics {
room (uuid: "${areaUuid}") {
visitsTimeStats(from: "${filters.from}", to: "${filters.to}") {
avgTime
}
}
}
}
}`);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment