Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
@wework/floormap-sdk
Advanced tools
[![CircleCI](https://circleci.com/gh/WeConnect/floormap-sdk/tree/master.svg?style=svg&circle-token=679c562fecb8e63401d492b82329d3d17a8c3430)](https://circleci.com/gh/WeConnect/floormap-sdk/tree/master) [![Coverage Status](https://coveralls.io/repos/github
NPM
npm install @wework/floormap-sdk
# Yarn
yarn add @wework/floormap-sdk
And import the SDK with:
import * as FloorMap from '@wework/floormap-sdk'
// you also can cherry-pick import a module from sdk by
// import { Manager } from '@wework/floormap-sdk'
UMD
By using the UMD format, You can access the SDK via FloorMap variable
<script type="text/javascript" src="floormap-sdk.min.js"></script>
In JavaScript
const manager = new FloorMap.Manager({ /* ... */ })
const floorMap = manager.createFloorMap(target, { /* ... */ })
Please see example/sample
for UMD usage
Before create and render a floor map, you need to authenticate with MilkyWay service by creating Manager
object and providing a credential
To request for an appId/appSecret, kindly email tech-sg@wework.com with the subject Request for FloorMap SDK credentials and a brief explanation of its intended purpose.
const manager = new FloorMap.Manager({
appId: /* App ID */,
appSecret: /* App Secret */,
baseUrl: 'https://occupancy-api-staging.spacemob.co',
})
Then, use .authenticate
function to start authenticating
manager.authenticate().then((mwAccessToken) => {
// Authenticated
}).catch((e) => {
// Authenticating Error
})
Spaceman JWT Token is supported directly by the SDK, You can pass Spaceman JWT while constructing maanger instance.
const manager = new FloorMap.Manager({
appId: /* App ID */,
appSecret: /* App Secret */,
baseUrl: 'https://occupancy-api-staging.spacemob.co',
spacemanToken: /* Spaceman JWT */
})
mwAccessToken
for futher usageauthenticate
function resolves mwAccessToken
object. You can store the access token object for futher use and provide the token object next time you're creating a manager.
manager.authenticate().then((mwAccessToken) => {
// Authenticated
localStorage.setItem('MW_TOKEN_STORAGE_KEY', JSON.stringify(mwAccessToken))
})
// Next time
const mwAccessToken = JSON.parse(localStorage.getItem('MW_TOKEN_STORAGE_KEY'))
const manager = new FloorMap.Manager({
/* ... */
mwAccessToken: mwAccessToken
})
After this point, the manager instance is ready to create and render the floormap.
First, create an emtry html element for the map to render itself
<body>
<section id="container"></section>
</body>
Next, Use maanger instance to create and render a floormap and provide target element.
const target = document.getElementById('container')
const floorMap = manager.createFloorMap(target, options)
FloorMap options
options.backgroundColor
- Background color of the mapoptions.deskLayout
- Show desk layoutoptions.deskInteractable
- Allow desk/chair to be interactableAfter created the floormap, Call render
function with buildingId
and floorId
to render a floor map into the screen (if floorId
is omitted, the lowest floor of the building will be rendered)
// Render Map
floorMap.render({
buildingId: 'b308b94c-bca6-4318-b906-1c148f7ca183',
/* floorId: '' */
})
Final source code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>FloorMap</title>
<style>
body {
margin: 0;
padding: 0;
}
#main {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="../../dist/floormap-sdk.js"></script>
<script>
async function renderMap() {
const target = document.getElementById('container')
let currentId = null
// Credential
const manager = new FloorMap.Manager({
appId: /* APP_ID */,
appSecret: /* APP_SECRET */,
baseUrl: 'https://occupancy-api-staging.spacemob.co',
})
// Authenticating
await manager.authenticate()
// Create Floor Map
const floorMap = manager.createFloorMap(target, {
backgroundColor: '#303030',
})
// Render Floor
floorMap.render({
buildingId: 'b308b94c-bca6-4318-b906-1c148f7ca183',
})
}
renderMap()
</script>
</body>
</html>
You can subscribe to user interaction and data event on the map by using addEventlistener
and removeEventListener
to remove a listener on the floor map instance
// Mouse moveover a space
floorMap.addEventListener('onmouseover', (event) => {})
// Mouse moveout a space
floorMap.addEventListener('onmouseout', (event) => {})
// On click a space
floorMap.addEventListener('onclick', (event) => {})
// When user moving mouse cursor on the map
floorMap.addEventListener('onmousemove', (event) => {})
// When physical data change
floorMap.addEventListener('datachange', (event) => {})
// Renderer event (mostly use for debugging purpose)
floorMap.addEventListener('onerror', (event) => {})
floorMap.addEventListener('onrender', (event) => {})
An event object will contain:
type
- Event typepayload
- An informations of the interactiondata
- Space data, If an interaction is on space/objectExample payload
{
"type": "onclick",
"payload": {
"id": "cdc9c84e-d092-11e7-9d13-0642b0acf810",
"point": { "x": 14.237798863250575, "y": 74.47726859122804, "z": -3 },
"mousePos": { "x": 530, "y": 203 }
},
"data": {
/* Space Data */
}
}
You can manipulate the style of space, table, and chair by using functions on floorMap instance:
applyStyle(spaceUUID, style, key)
- Apply style to spacerevertStyle(spaceUUID, key)
- Revert style with matched key from a given spaceresetStyle(spaceUUID)
- Reset all styles from a given spacefloorMap.applyStyle(spaceUUID, { color: 'aqua' }, 'highlight')
Style is Stack
When we call applyStyle
, we can think of pushing thing into the stack. If we call applyStyle
with different key, the later style will be push of top of the stack of overwrite property in previous items in the stack.
Also we call applyStyle
with a key that already exist in the stack, that style with key will be replaced with new style instead of merging and stay in the current position in the stack instead of bumb to the top
For example:
// Stack
//
// - somekey:{ color: 'red', opacity: 0.8 }
//
// result style: { color: 'red', opacity: 0.8 }
floorMap.applyStyle(spaceUUID, { color: 'red', opacity: 0.8 }, 'somekey')
// Apply style with new key `somekey`
//
// Stack
//
// - otherkey: { opacity: 0.5 }
// - somekey: { color: 'red', opacity: 0.8 }
//
// result style: { color: 'red', opacity: 0.5 }
floorMap.applyStyle(spaceUUID, { opacity: 0.5 }, 'otherkey')
// Apply style to existing key `somekey`
//
// Stack
//
// - otherkey: { opacity: 0.5 }
// - somekey: { color: 'red', opacity: 1.0 }
//
// result style: { color: 'red', opacity: 0.5 }
floorMap.applyStyle(spaceUUID, { color: 'red', opacity: 1.0 }, 'somekey')
// We revert 'somekey' style
// Stack
//
// - otherkey: { opacity: 0.5 }
//
// result style: { opacity: 0.5 }
floorMap.revertStyle(spaceUUID, 'somekey')
// Remove all style in stack
floorMap.resetStyle(spaceUUID)
// - Event Handling
floorMap.addEventListener('onmouseover', event => {
const { payload, data } = event
// Highlight Space
floorMap.applyStyle(payload.id, { color: 'aqua' }, 'HOVER')
})
floorMap.addEventListener('onmouseout', event => {
const { payload, data } = event
// unhighlight Space
floorMap.applyStyle(payload.id, {}, 'HOVER')
// You also can use revertStyle
// floorMap.revertStyle(payload.id, 'HOVER')
})
Map lifecycle give an opportunitues to you to start loading data along with when the map start loading data, modify physical data or apply style to an object before the map start render an object into the screen.
onLoad -> didLoad -> onRender -> didRender
onLoad hook allow you to prepare your own data while map start loading their data. You can return a Promise from the function, The map will wait until your Promise to be resolved before go to next lifecycle
floorMap.onLoad(({ buildingId, floorId }) => {
return fetch(/* ... */)
})
didLoad
will get called when the map finished loading their and the Promise from onLoad(s) has been resolved. You can use this function to modify the physical data in the map
floorMap.didLoad(({ buildingId, floorId }) => {
// Change room type
floorMap.updateData(spaceeUUID, { roomType: 'Private Large Office' })
})
onRender
will get called during the map is preparing render object for rendering into the screen, but not yet rendered into the screen. This function give you an opportunity to apply style to spaces.
floorMap.onRender({ buildingId, floorId } => {
floorMap.applyStyle(spaceUUID, { color: 'aqua'}, 'occupancy-style')
})
didRender
will get called when the map finished render objects into screen. You can add custom overlay into the map on this lifecycle (We will talk about map overlay in next section)
floorMap.didRender({ buildingId, floorId } => {
const imageOverlay = new ImageOverlay(noteIcon, {
width: 3,
height: 3,
})
imageOverlay.spaceUUID = spaceUUID
floorMap.addObject(imageOverlay)
})
const imageOverlay = new FloorMap.ImageOverlay(imageUrl, {
width: 3,
height: 3,
})
// Add image into space
// This will automatically calculate position of the image
imageOverlay.spaceUUID = '[PHYSICAL_SPACE_UUUD]'
floorMap.addObject(imageOverlay)
const textOverlay = new FloorMap.TextOverlay('FloorMapSDK!!')
textOverlay.position = { x: 0, y: 0, z: 0 }
textOverlay.scalar = 2
textOverlay.style = {
color: '#000000',
fontFamily: 'Arial, Helvetica, sans-serif',
textAlign: 'center',
fontWeight: 'normal', // normal, bold, bolder, lighter
fontStyle: 'normal', // normal, italic, oblique
}
floorMap.addObject(overlay)
const lineOverlay = new FloorMap.LineOverlay()
lineOverlay.style = {
color: '#303030'
}
lineOverlay.addPoint({ x: 100, y: 100 })
lineOverlay.addPoint({ x: 100, y: 200 })
// Add Overlay to floormap
floorMap.addObject(lineOverlay)
// Update point at index
// updatePoint(index, point)
lineOverlay.updatePoint(1, { x: 100, y: 300 })
// Remove point at index
// removePoint(index, point)
lineOverlay.removePoint(1, { x: 100, y: 300 })
// Update current overlay
floorMap.updateObject(lineOverlay)
const polygon = new FloorMap.PolygonOverlay(
[
{ x: x - 10, y: y - 10 },
{ x: x + 10, y: y - 10 },
{ x: x + 10, y: y + 10 },
{ x: x - 10, y: y + 10 },
],
{ color: 'aqua', opacity: 0.6 }
)
polygon.style = { color = '#000000', outline, opacity = 1 }
polygon.interactable = true
floorMap.addObject(polygon)
ImageOverlay
, TextOverlay
, LineOverlay
, and PloygonOverlay
are the abstractions of floormap.gl object. That means we can add floormap.gl's object using .addObject
function as well.
floorMap.addObject({
id: '001', // required
tags: ['level 3'],
type: 'MESH',
style: {
color: 'rgb(155, 255, 55)',
side: 'FRONT',
texture: {
img: '',
repeat: 0.5
}
outline: {
color: 'rgb(255, 0, 0)',
width: 0.2,
only: false
}
},
points: [
{ x: -1, y: -1 },
{ x: 1, y: -1 },
{ x: 1, y: 1 },
{ x: -1, y: 1 }
],
geometryTranslate: {x: -1, y: -1, z: 0},
interactable: true,
visible: true,
extrude: 2,
position: { x: 0, y: 0, z: 0 },
rotation: { x: 0, y: 0, z: 0 },
scale: { x: 1, y: 1, z: 1 }
})
The documentation on floormap.gl render object can be found on Floormap.GL repository
floorMap.addObject(overlay)
// You can add multiple objects as once by passing array of objects
floorMap.addObject([overlay, overlay2])
FloorMap overlay/object can be removed by calling .removeObject
with object or id
floorMap.removeObject(overlay)
floorMap.removeObject(id)
// Remove multiple objects as once
floorMap.removeObject([overlay1, overlay2])
floorMap.removeObject([id1, id2])
To position an overlay on the map we can set position
property.
const imageOverlay = new ImageOverlay()
imageOverlay.position = { x: 100, y: 100 }
floorMap.addObject(imageOverlay)
In case you want to add an overlay into the specific space/room. Instead of manually calculate the position of a room, we can omit position value and assign spaceUUID
to an overlay. The floor map will calculate the center position of the room and assign it to the overlay.
const imageOverlay = new ImageOverlay()
imageOverlay.spaceUUID = 'SPACE_UUID'
floorMap.addObject(imageOverlay)
To be added
# Clone
git clone git@github.com:WeConnect/floormap-sdk.git
cd floormap-sdk
# Install dependencies
yarn install
# Start demo and development
yarn start:demo
FAQs
[![CircleCI](https://circleci.com/gh/WeConnect/floormap-sdk/tree/master.svg?style=svg&circle-token=679c562fecb8e63401d492b82329d3d17a8c3430)](https://circleci.com/gh/WeConnect/floormap-sdk/tree/master) [![Coverage Status](https://coveralls.io/repos/github
The npm package @wework/floormap-sdk receives a total of 53 weekly downloads. As such, @wework/floormap-sdk popularity was classified as not popular.
We found that @wework/floormap-sdk demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 30 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.