Skip to content

Commit 295eb45

Browse files
authored
Merge pull request #91 from smplrspace/next
v2.32.0
2 parents 06da6e1 + 51cb40d commit 295eb45

File tree

14 files changed

+269
-309
lines changed

14 files changed

+269
-309
lines changed

.github/workflows/deploy.yml

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,53 @@ on:
55
- main
66

77
jobs:
8+
clickup-headsup:
9+
name: ClickUp heads-up
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Call ClickUp api
13+
uses: smplrspace/clickup-chat-action@v1
14+
with:
15+
workspace-id: 3887534
16+
channel-id: 3pmde-14775 # dev
17+
message: |
18+
🟣 Started: ${{ github.workflow}}
19+
env:
20+
CLICKUP_TOKEN: ${{ secrets.CLICKUP_BEEBOP_API_KEY }}
21+
822
deploy:
23+
name: Deploy docs
924
runs-on: ubuntu-latest
1025
permissions:
1126
contents: read
1227
deployments: write
1328
steps:
14-
- uses: actions/checkout@v2
15-
- uses: sarisia/actions-status-discord@v1
16-
with:
17-
webhook: ${{ secrets.DISCORD_WEBHOOK_DEV }}
18-
notimestamp: true
19-
nodetail: true
20-
title: "Started: ${{ github.workflow}} - ${{ github.ref_name }}"
21-
description: Triggered by ${{ github.actor }}
22-
color: 0x50545b
29+
- name: Checkout
30+
uses: actions/checkout@v2
2331
- name: Wait for Cloudflare Pages build
2432
uses: WalshyDev/cf-pages-await@v1
2533
with:
2634
apiToken: ${{ secrets.CF_API_TOKEN_PAGES }}
2735
accountId: "4955c8c28610ecabc384d84a20458a53"
2836
project: "docs"
29-
# write deplpyment status to github
37+
# write deployment status to github
3038
githubToken: ${{ secrets.PRIVATE_ACCESS_TOKEN_DEPLOYMENTS }}
31-
- name: Send Discord notification
32-
uses: sarisia/actions-status-discord@v1
33-
if: always()
39+
40+
clickup-notification:
41+
name: ClickUp notification
42+
if: always()
43+
needs:
44+
- deploy
45+
runs-on: ubuntu-latest
46+
steps:
47+
- uses: martialonline/workflow-status@v3
48+
id: check
49+
- name: Call ClickUp api
50+
uses: smplrspace/clickup-chat-action@v1
3451
with:
35-
webhook: ${{ secrets.DISCORD_WEBHOOK_DEV }}
36-
title: ${{ github.workflow}} - ${{ github.ref_name }}
37-
notimestamp: true
52+
workspace-id: 3887534
53+
channel-id: 3pmde-14775 # dev
54+
status-update: true
55+
status: ${{ steps.check.outputs.status }}
56+
env:
57+
CLICKUP_TOKEN: ${{ secrets.CLICKUP_BEEBOP_API_KEY }}

docs/api-reference/map/buildings.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ One of the main added "layer" the Smplrspace map viewer provides, as compared to
99

1010
## Spaces from Smplrspace
1111

12+
### List spaces by ID
13+
14+
To list the spaces that are currently rendered in the viewer by their IDs (something like "spc_xxx"), call:
15+
16+
```ts
17+
map.getCurrentSpaceIds() => string[]
18+
```
19+
1220
### Add spaces by ID
1321

1422
To fetch spaces from your Smplrspace account and render them on the map, call the following method. Note that the spaces need to be georeferenced within the platform.

docs/api-reference/map/custom-ux.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
sidebar_position: 3
2+
sidebar_position: 4
33
---
44

55
# Custom UX
@@ -34,13 +34,16 @@ interface MapSpaceRenderOptions {
3434

3535
### Update render options dynamically
3636

37-
Render options are described in details in [Render options](#render-options). You can update them dynamically with the method below:
37+
Render options are described in details in [Render options](#render-options). You can update them dynamically with the methods below:
3838

3939
```ts
4040
map.updateRenderOptions(options: MapSpaceRenderOptions) => void
41+
map.resetRenderOptionsToDefault() => void
4142
```
4243

43-
- `options` is an object of the [`MapSpaceRenderOptions`](#render-options) interface, which is deeply merged with the current options used by the viewer. To "unset" an optional value, you can pass `undefined` explicitely.
44+
- `updateRenderOptions` is used to update specific values, while keeping the others unchanged.
45+
- `options` is an object of the [`MapSpaceRenderOptions`](#render-options) interface, which is deeply merged with the current options used by the viewer. To "unset" an optional value, you can pass `undefined` explicitely.
46+
- `resetRenderOptionsToDefault` reverts all values to the Smplrspace defaults.
4447

4548
### Navigate levels
4649

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
---
2+
sidebar_position: 3
3+
---
4+
5+
# Data layers
6+
7+
To add or update data layers, you should use the type-specific methods detiled in [the next section](#types-of-layers), while other methods are shared between the layer types and documented [further down](#shared-methods).
8+
9+
## Types of layers
10+
11+
### Point layer
12+
13+
Coming soon — some methods are already present in the API but should not be used.
14+
15+
### Polygon layer
16+
17+
A polygon layer has each data element rendered as an extruded polygon. It is useful to highlight rooms or specific zones in the buildings.
18+
19+
```ts
20+
interface PolygonMapDataLayerDefinition {
21+
id: string,
22+
data: [{
23+
id: string,
24+
coordinates: [{
25+
levelIndex: number,
26+
x: number,
27+
z: number
28+
}] | [[{
29+
levelIndex: number,
30+
x: number,
31+
z: number
32+
}]],
33+
...customData: object
34+
}],
35+
baseHeight?: number | (dataElement: object) => number,
36+
height?: number | (dataElement: object) => number,
37+
color?: string | (dataElement: object) => string,
38+
// + fields from SharedDefinitionOptions defined further down
39+
}
40+
41+
map.addPolygonDataLayer(definition: PolygonMapDataLayerDefinition) => void
42+
map.updatePolygonDataLayer(definitionUpdates: Partial<PolygonMapDataLayerDefinition>) => void
43+
```
44+
45+
- `id` is a unique identifier for this layer which is used for updates.
46+
- `data` is an array of objects (refered to as data elements) to be rendered. Each element **must** have an `id` (unique identifier within the data array) and a `coordinates` array. Elements can also contain any additional custom data used for rendering options.
47+
- `coordinates` in its simple form is an array of points in the 2D horizontal space, it can also be an array of "rings" where the first ring is the external perimeter of the polygon, and the others are "holes" cut into the external perimeter.
48+
- `baseHeight` - _optional_ - defines the elevation from the ground at the base of the polygon in meters. It can be defined as a number for all elements or per element with a function that takes each element as argument and returns the base height for that element. _Default value: 0m._
49+
- `height` - _optional_ - defines the height of the polygon in meters from its base to its top. It can be defined as a number for all elements or per element with a function that takes each element as argument and returns the height for that element. _Default value: 3m._
50+
- `color` - _optional_ - defines the color of the element to render. It can be defined as any valid CSS color string like "orange" or "#3a3c3c", and applied for all elements or per element with a function that takes each element as argument and returns the color string for that element. _Default value: "#2393d4"_
51+
- `SharedDefinitionOptions` are defined [here](#shared-definition-options).
52+
53+
## Shared definition options
54+
55+
Some options correspond to generic behaviours that are shared by all data layers, making it easy to swap between similar layer types (e.g. "point" and "polygon").
56+
57+
```ts
58+
// not an actual interface, this is simplified for documentation
59+
interface SharedDefinitionOptions {
60+
tooltip?: (dataElement: object) => string | HTMLString,
61+
tooltipTemplate?: string,
62+
tooltipContainerStyle?: string,
63+
persistentTooltip?: boolean,
64+
legend?: LegendConfig, // see below
65+
onClick?: (dataElement: object, event: MapMouseEvent) => void,
66+
onHover?: (dataElement: object, event: MapMouseEvent) => void,
67+
onHoverOut?: (dataElement: object, event: MapMouseEvent) => void
68+
}
69+
70+
type LegendConfig =
71+
| {
72+
type: 'numeric'
73+
colorScale: (n: number | null | undefined) => string
74+
domain?: [number, number]
75+
ticks?: Record<number, number | string>
76+
}
77+
| {
78+
type: 'swatches'
79+
swatches: {
80+
color: string
81+
label: string
82+
group?: string
83+
}[]
84+
}
85+
| {
86+
type: 'icons'
87+
icons: {
88+
url: string
89+
label: string
90+
group?: string
91+
}[]
92+
}
93+
```
94+
95+
- `tooltip` - _optional_ - is taking the newly hovered data element as argument and should return the content of the tooltip to render. It is called once when the pointer starts to hover a data element. Built-in tooltips support string and "HTML as string" values.
96+
- For string values, newlines are supported by using [multi-line template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#multi-line_strings).
97+
- For HTML values, both HTML and CSS are supported, the value will be sanitized to prevent XSS attacks.
98+
- If you need complete control over the tooltip content (e.g. for a React component), check the [tooltips example](/examples/tooltips/).
99+
- `tooltipTemplate` - _optional_ - is a fully featured template string used to generate the tooltip content based on the data for the hovered element.
100+
- It is powered by [Handlebars](https://handlebarsjs.com/) and you may refer to the full templating documentation [here](https://handlebarsjs.com/guide/).
101+
- It supports HTML, nested fields access, conditionals, loops, and more.
102+
- A custom helper lets you use fallback default values: `{{fallback [my field] 'default value'}}`.
103+
- Without this helper, we use `'-'` as a default value for all fields.
104+
- `tooltipContainerStyle` - _optional_ - lets you override the style of the tooltip container with inline CSS.
105+
- `persistentTooltip` - _optional_ - set this to `true` to turn tooltips into small cards that are all visible at once instead of on hover. Persistent tooltips are automatically positioned on the center of the data element they're attached to (limitation: elevation of the element is not accounted for at the moment). _Default value: false_
106+
- `legend` - _optional_ - lets you configure a legend to be rendered automatically in a collapsible overlay on the viewer. The legend can be positioned using `legendPosition` in [viewer options](/api-reference/space/custom-ux#viewer-options).
107+
- For `numeric` legends, refer to options in [the legend section](/api-reference/color/legend#numerical-scale-legends).
108+
- For `swatches` legends, refer to options in [the legend section](/api-reference/color/legend#categorical-scale-legends).
109+
- For `icons` legends, refer to options in [the legend section](/api-reference/color/legend#icons-legends).
110+
- `onClick` - _optional_ - is taking the data element that was clicked as argument, as well as the [Mapbox mouse event](https://docs.mapbox.com/mapbox-gl-js/api/events/#mapmouseevent) that triggered the click. It is called each time a click or tap event happens.
111+
- `onHover` - _optional_ - is taking the newly hovered data element as argument, as well as the [Mapbox mouse event](https://docs.mapbox.com/mapbox-gl-js/api/events/#mapmouseevent) that triggered the click. The handler is called once when the pointer starts to hover a data element.
112+
- `onHoverOut` - _optional_ - is taking the previously hovered data element as argument, as well as the [Mapbox mouse event](https://docs.mapbox.com/mapbox-gl-js/api/events/#mapmouseevent) that triggered the click. The handler is called once when the pointer stops hovering a data element.
113+
114+
You may use the `onClick`, `onHover` and `onHoverOut` handlers to build custom behaviours in your app that respond to interactions happening in the floor plan.
115+
116+
117+
## Shared methods
118+
119+
### Get a data element position on screen
120+
121+
This method lets you get the screen position of a data element. This can be useful to implement custom tooltips that you have full programmatic control over.
122+
123+
```ts
124+
map.getDataElementPositionOnScreen(layerId: string, elementId: string) => ({
125+
screenX: number
126+
screenY: number
127+
}) | null
128+
```
129+
130+
- `layerId` is the `id` field in your layer's definition
131+
- `elementId` corresponds to the `id` field used in the `data` array of your layer
132+
133+
If an element is found matching `layerId` and `elementId`, the function returns its coordinates when projected on screen. When no element is found, the function returns `null`.
134+
135+
**Take good note:**
136+
1. The elevation of the element is not accounted for at the moment, due to limitations in the Mapbox APIs.
137+
1. `screenX` and `screenY` are not bounded by the viewer itself, so you could have negative values, or values greater that the size of the viewer if the element is present in the 3D scene, but located outside of the current view.
138+
139+
### Remove a layer
140+
141+
Removing a data layer completely is done as follow.
142+
143+
```ts
144+
map.removeDataLayer(id: string) => void
145+
```
146+
147+
- `id` is the identifier of the layer to remove.
148+
149+
### Remove all layers
150+
151+
Removing all data layers at once is done as follow.
152+
153+
```ts
154+
map.removeAllDataLayers() => void
155+
```

docs/api-reference/map/map.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ map.startViewer({
4343
onReady?: () => void
4444
onError?: (errorMessage: string) => void
4545
onSpaceClick?: ({ space, levelIndex }: { space: object | undefined; levelIndex: number }) => void
46+
legendPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
4647
}) => Promise<void>
4748
```
4849

@@ -55,6 +56,7 @@ map.startViewer({
5556
- `onReady` - _optional_ - is called once the viewer's initial render is done. You may alternatively use the promise returned by startViewer, which resolves when the viewer is ready.
5657
- `onError` - _optional_ - is called if an error occur while starting the viewer. You may alternatively use the promise returned by startViewer to catch errors.
5758
- `onSpaceClick` - _optional_ - is called when the user clicks a 3D space, and provide data about which space and which level where clicked.
59+
- `legendPosition` - _optional_ - lets you choose where the legend (if any is configured in the data layers) would be rendered. _Default value: 'top-left'_
5860

5961
Calling `startViewer` returns a `Promise` ([MDN docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)) which resolves when the viewer is ready. This lets you use `Promise.then().catch()` or `async/await` with a `try/catch` block to react when the viewer is ready, or to handle errors that may occur. It is an alternative to providing `onReady` and `onError` callback methods. You may choose the option that suits the most your environment or coding style.
6062

@@ -66,10 +68,22 @@ To stop the viewer, dispose of resources it allocated, and clear the container i
6668
space.remove() => void
6769
```
6870

71+
### Check if the viewer is ready
72+
73+
To check if the viewer has finished initializing and is ready for API methods to be called, you can do:
74+
75+
```ts
76+
space.isViewerStarted() => boolean
77+
```
78+
6979
## Render buildings
7080

7181
See the dedicated functions you can call to render buildings [on this page](/api-reference/map/buildings).
7282

83+
## Data layers
84+
85+
The map viewer includes a full SDK to render data layers. Learn more [on this page](/api-reference/map/data-layers).
86+
7387
## Control the map location
7488

7589
### Focus on a specific space
@@ -91,6 +105,8 @@ You can change automatically "fly" the map to an overview point, showing all ren
91105
map.fitAllSpacesInScreen() => void
92106
```
93107

108+
In case their is a single space rendered, this method will be equivalent to calling [`flyToSpace`](#focus-on-a-specific-space) on that space.
109+
94110
## UI controls
95111

96112
### Change the loading message

0 commit comments

Comments
 (0)