Skip to content

Floor Plan SDK guide

A modern Typescript SDK for dynamic display of floor plans

INFO

This page documents Floor Plan SDK v5, which requires Space Graph.
Looking for the older v3 version or information on migration?

Overview

The Floor Plan SDK enables you to create interactive, customizable floor plan models embedded in your website using JavaScript or TypeScript.

Interactive example (you can zoom or pan the plan):

Quick start

Install the Floor Plan SDK JS package via npm.

bash
npm install @archilogic/floor-plan-sdk

You can then import it into your project:

html
<div id="floor-plan"></div>
ts
import '@archilogic/floor-plan-sdk/dist/style.css'
import { FloorPlanEngine } from '@archilogic/floor-plan-sdk'

const container = document.getElementById('floor-plan')
const floorPlan = new FloorPlanEngine({ container })

// Create publishable access token at https://app.archilogic.com/organization/settings/access-tokens
const publishableAccessToken = '<your-token>'
const floorId = '<your-floor-id>'
floorPlan.loadFloorById(floorId, { publishableAccessToken })

Startup Options

The FloorPlanEngine has an optional parameter options. See below the various options that can be set through this parameter. The options are passed like the following:

js
new FloorPlanEngine({ container, options })

Options can be changed at runtime using the set method

js
floorPlan.set(options)

Theme

The SDK offers a wide range of theming options.

Spaces can be colored programmatically following the Space Taxonomy. The following snippet colors all work spaces blue.

js
const options = {
  theme: {
    elements: {
      'layout:space': {
        program: {
          work: { fill: [214, 234, 248] }
        }
      }
    }
  }
}
const floorPlan = new FloorPlanEngine({ container, options })
floorPlan.loadFloorById(floorId, { publishableAccessToken })
ts
import type { FpeConfig } from '@archilogic/floor-plan-sdk'

const options: FpeConfig = {
  theme: {
    elements: {
      'layout:space': {
        program: {
          work: { fill: [214, 234, 248] }
        }
      }
    }
  }
}
const floorPlan = new FloorPlanEngine({ container, options })
floorPlan.loadFloorById(floorId, { publishableAccessToken })

Custom room stamp content

roomStampDisplay allows to set the properties and their order for all room stamps shown in the floor plan.

The default value is ['usage', 'area'].

js
const attributeId = 'department-name'
const options = {
  theme: {
    elements: {
      roomStamp: {
        roomStampDisplay: [
          'name',
          'customId',
          'usage',
          'area',
          ['customAttribute', attributeId]
        ]
      }
    }
  }
}
const floorPlan = new FloorPlanEngine({ container, options })
floorPlan.loadFloorById(floorId, { publishableAccessToken })
ts
import type { FpeConfig } from '@archilogic/floor-plan-sdk'

const attributeId = 'department-name'
const options: FpeConfig = {
  theme: {
    elements: {
      roomStamp: {
        roomStampDisplay: [
          'name',
          'customId',
          'usage',
          'area',
          ['customAttribute', attributeId]
        ]
      }
    }
  }
}
const floorPlan = new FloorPlanEngine({ container, options })
floorPlan.loadFloorById(floorId, { publishableAccessToken })

To set a name, customId for a space, you can use the Archilogic Editor.
Custom attributes are user defined properties, that can be defined for an organisation in the Dashboard or via API and then edited in the Editor.

Space label mapping

Map space labels by space usage or space id. Refer to the space taxonomy for reference.

js
const options = {
  spaceLabelMapping: {
    meetingRoom: '회의실'
  }
}
const floorPlan = new FloorPlanEngine({ container, options })
floorPlan.loadFloorById(demoSceneId, { publishableAccessToken })

Resources

When the promise returned by loadFloorById is resolved, we can expect that the layout.spaces and layout.elements are populated with the Space and Asset nodes. Each space references the assets that it contains by their unique id. This allows you to know what's in each space.

Space

Sample space:

ts
await floorPlan.loadFloorById('a9aaafdf-d5b6-4b4a-82a0-9efb6d5b155a', { publishableAccessToken })
const space: LayoutSpace = floorPlan.layout.spaces[0]

class LayoutSpace {
  type: "layout:space"
  // unique id for the space
  id: string
  // custom name
  name: string
  // custom id
  customId: string
  attributes: {
    // assigned usage function
    usage: string
    // space category
    program: string
  }
  // get the contained assets in the space
  getElements('element:asset'): LayoutAsset[]
}

Visit the Space Graph documentation for more details and the space taxonomy.

Asset

Sample asset:

ts
// get an asset that is referenced by the space above
const asset: LayoutAsset = floorPlan.layout.elementsById[assetId]

class LayoutAsset {
  type: 'element:asset'
  // unique id for the asset
  id: string
  // [x, y, z] - right handed coordinate system, y is up
  position: Vector3
  // rotation around the y axis in degrees
  rotation: number
  // multiple assets can reference the same product definition
  product: SpaceGraphProduct
  // get the space the asset is in
  getSpaces(): LayoutSpace[]
}

class SpaceGraphProduct {
  id: string
  // product metadata (generic or real)
  name: string
  attributes: {
    // product category
    categories: string[]
    // product subCategory
    subCategories: string[]
    // product dimensions
    boundingBox: BoundingBox3d
  }
}

Take a look at the product taxonomy for reference. And visit the Space Graph documentation for more details.

Events

The FloorPlanEngine instance exposes a few useful events

Subscribe

js
floorPlan.on(event, callback, context)

Subscribe for one event

js
floorPlan.once(event, callback, context)

Unsubscribe

js
floorPlan.off(event, callback)

click

Mouse click or touch event.

Instead of click you can also listen for dblclick

js
// returns the plan position, the sourceEvent and if present the id of the node that you clicked on
floorPlan.on('click', onClick)

function onClick({ position, sourceEvent, nodeId }) {
  // to get the top resource that was clicked on use the nodeId
  const asset = floorPlan.layout.elementsById[nodeId]
  const space = floorPlan.layout.spacesById[nodeId]
  // to get all resources for that position use the position
  const { assets, spaces } = floorPlan.getResourcesFromPosition(position)
}
ts
import type { FpePointerEvent } from '@archilogic/floor-plan-sdk'

// returns the plan position, the sourceEvent and if present the id of the node that you clicked on
floorPlan.on('click', onClick)

function onClick({ position, sourceEvent, nodeId }: FpePointerEvent) {
  // to get the top resource that was clicked on use the nodeId
  const asset = nodeId && floorPlan.layout.elementsById[nodeId]
  const space = nodeId && floorPlan.layout.spacesById[nodeId]
  // to get all resources for that position use the position
  const { assets, spaces } = floorPlan.getResourcesFromPosition(position)
}

mousemove

Fired when moving the mouse

js
floorPlan.on('mousemove', onMouseMove)

function onMouseMove({ position, sourceEvent, nodeId }) {
  // ...
}
ts
import type { FpePointerEvent } from '@archilogic/floor-plan-sdk'

floorPlan.on('mousemove', onMouseMove)

function onMouseMove({ position, sourceEvent, nodeId }: FpePointerEvent) {
  // ...
}

drop

Fired when dropping a draggable Element on the canvas

js
floorPlan.on('drop', onDrop)

function onDrop({ position, sourceEvent, nodeId }) {
  // ...
}
ts
import type { FpeDropEvent } from '@archilogic/floor-plan-sdk'

floorPlan.on('drop', onDrop)

function onDrop({ position, sourceEvent }: FpeDropEvent) {
  // ...
}

loading done

Fired when loading is done and the floor is rendered. This is an alternative to awaiting the promise of floorPlan.loadFloorById().

js
floorPlan.on('loading-done', onLoadingDone)

function onLoadingDone() {
  // ...
}

Zoom

The SDK provides various zoom methods

Zoom extents

Allows you to zoom to the extent of the scene, with a specified margin using zoomExtents.

Zoom to element

You can also zoom into an element (space, asset) with or without animation using the zoomToElement method.

js
// get a space ID
const spaceId = floorPlan.layout.spaces[0].id
// zoom to the space with 2m margin and 500ms animation time
floorPlan.zoomToElement(spaceId, 2, 500)

Zoom by factor

Zoom the current view by a factor with zoomByFactor. A zoom factor, larger than 1 zooms in, smaller than 1 zooms out.

js
floorPlan.zoomByFactor(1.2, true)

Set zoom

Set the view box by providing a bounding box using the setZoom method.

Methods

Add marker

The addMarker method can be used to add extra information to a given location within the floor plan. It requires the following parameters:

ts
floorPlan.addMarker({
  position: [7, 2],
  color: '#0c9'
})

Where

  • position is the position on the floor plan specified in meters where the info window points
  • width, height specifies the size of the info window

Returns Marker instance

Add info window

The addInfoWindow method can be used to add extra information to a given location within the floor plan. It requires the following parameters:

ts
floorPlan.addInfoWindow({
  position: [7, 2],
  width: 200,
  height: 80,
  html: '<h1>Note</h1><p>This room has 3 desks</p>',
  closeButton: true
})

Where

  • position is the position on the floor plan specified in meters where the info window points
  • width, height specifies the size of the info window
  • html is the user-specified content to be displayed
  • closeButton if true displays a close button

Returns InfoWindow instance

Add Html marker

The addHtmlMarker method can be used to add extra information to a given location within the floor plan. It requires the following parameters:

ts
const el = document.createElement('div')
el.classList.add('my-marker')
floorPlan.addHtmlMarker({
  position: [7, 2],
  el
})

Where

  • position is the position on the floor plan specified in meters where the info window points
  • el is the HTML Element that you want to mount at that position

Returns Html Marker instance

Add layer and graphics

js
const layer = floorPlan.addLayer({ id: 'circles' })
const list = Array.from({ length: 15 }, (_, i) => i + 1)

layer.addGraphic({
  shapes: list.map(radius => ({
    type: 'curve:circle',
    radius,
    position: [0, 0],
    style: { stroke: '#ffab00', strokeWidth: radius * 2 }
  }))
})
ts
import type { Shape } from '@archilogic/floor-plan-sdk'

const layer = floorPlan.addLayer({ id: 'circles' })
const list: number[] = Array.from({ length: 15 }, (_, i) => i + 1)

layer.addGraphic({
  shapes: list.map<Shape>(radius => ({
    type: 'curve:circle',
    radius,
    position: [0, 0],
    style: { stroke: '#ffab00', strokeWidth: radius * 2 }
  }))
})

Get resources from position

From a given plan position the getResourcesFromPosition methods returns the assets and spaces for that position.

js
floorPlan.on('click', handleClick, floorPlan)

function handleClick(evt) {
  // returns the plan position, the sourceEvent and if present the id of the node that you clicked on
  const { position, sourceEvent, nodeId } = evt
  // get a list of assets and spaces for that plan position
  const { assets, spaces } = this.getResourcesFromPosition(position)
  // proceed by highlighting the resources in focus for instance
}

Highlight a resource

All exposed resources can be colored programmatically floorPlan.drawNodeUpdate

js
// use the setHighlight method to temporarily change its color and its outline
floorPlan.drawNodeUpdate('<node-id>', {
  fill: [236, 112, 99],
  stroke: [200, 42, 25],
  strokeWidth: 2
})
// use the same method to reset the color
floorPlan.drawNodeUpdate('<node-id>', false)

Example

Color all assets based on their position

ts
const floorPlan = new FloorPlanEngine({ container })
floorPlan.loadFloorById(floorId, { publishableAccessToken }).then(() => {
  highlightNodes()
})

function highlightNodes() {
  for (const asset of floorPlan.layout.elementsByType['element:asset']) {
    floorPlan.drawNodeUpdate(asset.id, {
      fill: asset.position.map(n => Math.round(n) * 10)
    })
  }
}

Save floor plan as image

A method is provided to save the displayed floor plan as either jpg of png image: exportImage

js
floorPlan.exportImage({
  download: true,
  format: 'jpg'
})