93 changed files with 1214 additions and 349 deletions
@ -0,0 +1,151 @@ |
|||
///
|
|||
/// Copyright © 2016-2025 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { EntityAliases, EntityAliasInfo, getEntityAliasId } from '@shared/models/alias.models'; |
|||
import { FilterInfo, Filters, getFilterId } from '@shared/models/query/query.models'; |
|||
import { Dashboard } from '@shared/models/dashboard.models'; |
|||
import { DatasourceType, Widget } from '@shared/models/widget.models'; |
|||
import { BaseMapSettings, MapDataSourceSettings, MapType } from '@shared/models/widget/maps/map.models'; |
|||
import { WidgetExportDefinition } from '@shared/models/widget/widget-export.models'; |
|||
|
|||
interface ExportDataSourceInfo { |
|||
aliases: {[dataLayerIndex: number]: EntityAliasInfo}; |
|||
filters: {[dataLayerIndex: number]: FilterInfo}; |
|||
} |
|||
|
|||
interface MapDatasourcesInfo { |
|||
trips?: ExportDataSourceInfo; |
|||
markers?: ExportDataSourceInfo; |
|||
polygons?: ExportDataSourceInfo; |
|||
circles?: ExportDataSourceInfo; |
|||
additionalDataSources?: ExportDataSourceInfo; |
|||
} |
|||
|
|||
export const MapExportDefinition: WidgetExportDefinition<MapDatasourcesInfo> = { |
|||
testWidget(widget: Widget): boolean { |
|||
if (widget?.config?.settings) { |
|||
const settings = widget.config.settings; |
|||
if (settings.mapType && [MapType.image, MapType.geoMap].includes(settings.mapType)) { |
|||
if (settings.trips && Array.isArray(settings.trips)) { |
|||
return true; |
|||
} |
|||
if (settings.markers && Array.isArray(settings.markers)) { |
|||
return true; |
|||
} |
|||
if (settings.polygons && Array.isArray(settings.polygons)) { |
|||
return true; |
|||
} |
|||
if (settings.circles && Array.isArray(settings.circles)) { |
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
return false; |
|||
}, |
|||
prepareExportInfo(dashboard: Dashboard, widget: Widget): MapDatasourcesInfo { |
|||
const settings: BaseMapSettings = widget.config.settings as BaseMapSettings; |
|||
const info: MapDatasourcesInfo = {}; |
|||
if (settings.trips?.length) { |
|||
info.trips = prepareExportDataSourcesInfo(dashboard, settings.trips); |
|||
} |
|||
if (settings.markers?.length) { |
|||
info.markers = prepareExportDataSourcesInfo(dashboard, settings.markers); |
|||
} |
|||
if (settings.polygons?.length) { |
|||
info.polygons = prepareExportDataSourcesInfo(dashboard, settings.polygons); |
|||
} |
|||
if (settings.circles?.length) { |
|||
info.circles = prepareExportDataSourcesInfo(dashboard, settings.circles); |
|||
} |
|||
if (settings.additionalDataSources?.length) { |
|||
info.additionalDataSources = prepareExportDataSourcesInfo(dashboard, settings.additionalDataSources); |
|||
} |
|||
return info; |
|||
}, |
|||
updateFromExportInfo(widget: Widget, entityAliases: EntityAliases, filters: Filters, info: MapDatasourcesInfo): void { |
|||
const settings: BaseMapSettings = widget.config.settings as BaseMapSettings; |
|||
if (info?.trips) { |
|||
updateMapDatasourceFromExportInfo(entityAliases, filters, settings.trips, info.trips); |
|||
} |
|||
if (info?.markers) { |
|||
updateMapDatasourceFromExportInfo(entityAliases, filters, settings.markers, info.markers); |
|||
} |
|||
if (info?.polygons) { |
|||
updateMapDatasourceFromExportInfo(entityAliases, filters, settings.polygons, info.polygons); |
|||
} |
|||
if (info?.circles) { |
|||
updateMapDatasourceFromExportInfo(entityAliases, filters, settings.circles, info.circles); |
|||
} |
|||
if (info?.additionalDataSources) { |
|||
updateMapDatasourceFromExportInfo(entityAliases, filters, settings.additionalDataSources, info.additionalDataSources); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
const updateMapDatasourceFromExportInfo = (entityAliases: EntityAliases, |
|||
filters: Filters, settings: MapDataSourceSettings[], info: ExportDataSourceInfo): void => { |
|||
if (info.aliases) { |
|||
for (const dsIndexStr of Object.keys(info.aliases)) { |
|||
const dsIndex = Number(dsIndexStr); |
|||
if (settings[dsIndex] && settings[dsIndex].dsType === DatasourceType.entity) { |
|||
const aliasInfo = info.aliases[dsIndex]; |
|||
settings[dsIndex].dsEntityAliasId = getEntityAliasId(entityAliases, aliasInfo); |
|||
} |
|||
} |
|||
} |
|||
if (info.filters) { |
|||
for (const dsIndexStr of Object.keys(info.filters)) { |
|||
const dsIndex = Number(dsIndexStr); |
|||
if (settings[dsIndex] && settings[dsIndex].dsType === DatasourceType.entity) { |
|||
const filterInfo = info.filters[dsIndex]; |
|||
settings[dsIndex].dsFilterId = getFilterId(filters, filterInfo); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
const prepareExportDataSourcesInfo = (dashboard: Dashboard, settings: MapDataSourceSettings[]): ExportDataSourceInfo => { |
|||
const info: ExportDataSourceInfo = { |
|||
aliases: {}, |
|||
filters: {} |
|||
}; |
|||
settings.forEach((dsSettings, index) => { |
|||
prepareExportDataSourceInfo(dashboard, info, dsSettings, index); |
|||
}); |
|||
return info; |
|||
} |
|||
|
|||
const prepareExportDataSourceInfo = (dashboard: Dashboard, info: ExportDataSourceInfo, settings: MapDataSourceSettings, index: number): void => { |
|||
if (settings.dsType === DatasourceType.entity) { |
|||
const entityAlias = dashboard.configuration.entityAliases[settings.dsEntityAliasId]; |
|||
if (entityAlias) { |
|||
info.aliases[index] = { |
|||
alias: entityAlias.alias, |
|||
filter: entityAlias.filter |
|||
}; |
|||
} |
|||
if (settings.dsFilterId && dashboard.configuration.filters) { |
|||
const filter = dashboard.configuration.filters[settings.dsFilterId]; |
|||
if (filter) { |
|||
info.filters[index] = { |
|||
filter: filter.filter, |
|||
keyFilters: filter.keyFilters, |
|||
editable: filter.editable |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
///
|
|||
/// Copyright © 2016-2025 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { Widget } from '@shared/models/widget.models'; |
|||
import { Dashboard } from '@shared/models/dashboard.models'; |
|||
import { EntityAliases } from '@shared/models/alias.models'; |
|||
import { Filters } from '@shared/models/query/query.models'; |
|||
import { MapExportDefinition } from '@shared/models/widget/maps/map-export.models'; |
|||
|
|||
export interface WidgetExportDefinition<T = any> { |
|||
testWidget(widget: Widget): boolean; |
|||
prepareExportInfo(dashboard: Dashboard, widget: Widget): T; |
|||
updateFromExportInfo(widget: Widget, entityAliases: EntityAliases, filters: Filters, info: T): void; |
|||
} |
|||
|
|||
const widgetExportDefinitions: WidgetExportDefinition[] = [ |
|||
MapExportDefinition |
|||
]; |
|||
|
|||
export const getWidgetExportDefinition = (widget: Widget): WidgetExportDefinition => { |
|||
return widgetExportDefinitions.find(def => def.testWidget(widget)); |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
#### Clustering marker function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, childCount): string* |
|||
|
|||
A JavaScript function used to compute clustering marker color. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
<li><b>data:</b> <code><a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts#L108" target="_blank">FormattedData[]</a></code> |
|||
- the array of total markers contained within each cluster.<br/> |
|||
Represents basic entity properties (ex. <code>entityId</code>, <code>entityName</code>)<br/>and provides access to other entity attributes/timeseries declared in widget datasource configuration. |
|||
</li> |
|||
<li><b>childCount:</b> <code>number</code> - the total number of markers contained within that cluster |
|||
</li> |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting color of the marker. |
|||
|
|||
In case no data is returned, color value from **Color** settings field will be used. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
##### Examples |
|||
|
|||
<ul> |
|||
<li> |
|||
Calculate color depending on temperature telemetry value: |
|||
</li> |
|||
|
|||
|
|||
```javascript |
|||
let customColor; |
|||
for (let markerData of data) { |
|||
if (markerData.temperature > 40) { |
|||
customColor = 'red' |
|||
} |
|||
} |
|||
return customColor ? customColor : 'green'; |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<li> |
|||
Calculate color depending on childCount: |
|||
</li> |
|||
|
|||
```javascript |
|||
if (childCount < 10) { |
|||
return 'green'; |
|||
} else if (childCount < 100) { |
|||
return 'yellow'; |
|||
} else { |
|||
return 'red'; |
|||
} |
|||
{:copy-code} |
|||
``` |
|||
|
|||
</ul> |
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,42 @@ |
|||
#### Marker color function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData, dsIndex): string* |
|||
|
|||
A JavaScript function used to compute color of the marker. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map-legacy/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting color of the marker. |
|||
|
|||
In case no data is returned, color value from **Color** settings field will be used. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
##### Examples |
|||
|
|||
* Calculate color depending on `temperature` telemetry value for `colorpin` device type: |
|||
|
|||
```javascript |
|||
var type = data['Type']; |
|||
if (type == 'colorpin') { |
|||
var temperature = data['temperature']; |
|||
if (typeof temperature !== undefined) { |
|||
var percent = (temperature + 60)/120 * 100; |
|||
return tinycolor.mix('blue', 'red', percent).toHexString(); |
|||
} |
|||
return 'blue'; |
|||
} |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,40 @@ |
|||
#### Marker label function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData, dsIndex): string* |
|||
|
|||
A JavaScript function used to compute text or HTML code of the marker label. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map-legacy/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting text or HTML of the marker label. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
##### Examples |
|||
|
|||
* Display styled label with corresponding latest telemetry data for `energy meter` or `thermometer` device types: |
|||
|
|||
```javascript |
|||
var deviceType = data['Type']; |
|||
if (typeof deviceType !== undefined) { |
|||
if (deviceType == "energy meter") { |
|||
return '<span style="color:orange;">${entityName}, ${energy:2} kWt</span>'; |
|||
} else if (deviceType == "thermometer") { |
|||
return '<span style="color:blue;">${entityName}, ${temperature:2} °C</span>'; |
|||
} |
|||
} |
|||
return data.entityName; |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,10 @@ |
|||
<li><b>data:</b> <code><a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts#L108" target="_blank">FormattedData</a></code> - A <a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts#L108" target="_blank">FormattedData</a> object associated with marker or data point of the route.<br/> |
|||
Represents basic entity properties (ex. <code>entityId</code>, <code>entityName</code>)<br/>and provides access to other entity attributes/timeseries declared in widget datasource configuration. |
|||
</li> |
|||
<li><b>dsData:</b> <code><a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts#L108" target="_blank">FormattedData[]</a></code> - All available data associated with markers or routes data points as array of <a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts#L108" target="_blank">FormattedData</a> objects<br/> |
|||
resolved from configured datasources. Each object represents basic entity properties (ex. <code>entityId</code>, <code>entityName</code>)<br/> |
|||
and provides access to other entity attributes/timeseries declared in widget datasource configuration. |
|||
</li> |
|||
<li><b>dsIndex</b> <code>number</code> - index of the current marker data or route data point in <code>dsData</code> array.<br> |
|||
<strong>Note: </strong> The <code>data</code> argument is equivalent to <code>dsData[dsIndex]</code> expression. |
|||
</li> |
|||
@ -0,0 +1,62 @@ |
|||
#### Marker image function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, images, dsData, dsIndex): {url: string, size: number}* |
|||
|
|||
A JavaScript function used to compute marker image. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map-legacy/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return marker image data having the following structure: |
|||
|
|||
```typescript |
|||
{ |
|||
url: string, |
|||
size: number |
|||
} |
|||
``` |
|||
|
|||
- *url* - marker image url; |
|||
- *size* - marker image size; |
|||
|
|||
In case no data is returned, default marker image will be used. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
##### Examples |
|||
|
|||
<ul> |
|||
<li> |
|||
Calculate image url depending on <code>temperature</code> telemetry value for <code>thermometer</code> device type.<br> |
|||
Let's assume 4 images are defined in <b>Marker images</b> section. Each image corresponds to particular temperature level: |
|||
</li> |
|||
</ul> |
|||
|
|||
```javascript |
|||
var type = data['Type']; |
|||
if (type == 'thermometer') { |
|||
var res = { |
|||
url: images[0], |
|||
size: 40 |
|||
} |
|||
var temperature = data['temperature']; |
|||
if (typeof temperature !== undefined) { |
|||
var percent = (temperature + 60)/120; |
|||
var index = Math.min(3, Math.floor(4 * percent)); |
|||
res.url = images[index]; |
|||
} |
|||
return res; |
|||
} |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,42 @@ |
|||
#### Path color function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData, dsIndex): string* |
|||
|
|||
A JavaScript function used to compute color of the trip path. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map-legacy/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting color of the trip path. |
|||
|
|||
In case no data is returned, color value from **Path color** settings field will be used. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
##### Examples |
|||
|
|||
* Calculate color depending on `temperature` telemetry value for `colorpin` device type: |
|||
|
|||
```javascript |
|||
var type = data['Type']; |
|||
if (type == 'colorpin') { |
|||
var temperature = data['temperature']; |
|||
if (typeof temperature !== undefined) { |
|||
var percent = (temperature + 60)/120 * 100; |
|||
return tinycolor.mix('blue', 'red', percent).toHexString(); |
|||
} |
|||
return 'blue'; |
|||
} |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,43 @@ |
|||
#### Path point color function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData, dsIndex): string* |
|||
|
|||
A JavaScript function used to compute color of the trip path point. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map-legacy/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting color of the trip path point. |
|||
|
|||
In case no data is returned, color value from **Point color** settings field will be used. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
##### Examples |
|||
|
|||
* Calculate color depending on `temperature` telemetry value for `colorpin` device type: |
|||
|
|||
```javascript |
|||
var type = data['Type']; |
|||
if (type == 'colorpin') { |
|||
var temperature = data['temperature']; |
|||
if (typeof temperature !== undefined) { |
|||
var percent = (temperature + 60)/120 * 100; |
|||
return tinycolor.mix('blue', 'red', percent).toHexString(); |
|||
} |
|||
return 'blue'; |
|||
} |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
|
|||
@ -0,0 +1,40 @@ |
|||
#### Polygon tooltip function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData, dsIndex): string* |
|||
|
|||
A JavaScript function used to compute text or HTML code to be displayed in the polygon tooltip. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map-legacy/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting text or HTML for the polygon tooltip. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
##### Examples |
|||
|
|||
* Display details with corresponding telemetry data for `energy meter` or `thermostat` device types: |
|||
|
|||
```javascript |
|||
var deviceType = data['Type']; |
|||
if (typeof deviceType !== undefined) { |
|||
if (deviceType == "energy meter") { |
|||
return '<b>${entityName}</b><br/><b>Energy:</b> ${energy:2} kWt<br/>'; |
|||
} else if (deviceType == "thermostat") { |
|||
return '<b>${entityName}</b><br/><b>Temperature:</b> ${temperature:2} °C<br/>'; |
|||
} |
|||
} |
|||
return data.entityName; |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,65 @@ |
|||
#### Position conversion function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (origXPos, origYPos, data, dsData, dsIndex, aspect): {x: number, y: number}* |
|||
|
|||
A JavaScript function used to convert original relative x, y coordinates of the marker. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
<li><b>origXPos:</b> <code>number</code> - original relative x coordinate as double from 0 to 1.</li> |
|||
<li><b>origYPos:</b> <code>number</code> - original relative y coordinate as double from 0 to 1.</li> |
|||
{% include widget/lib/map-legacy/map_fn_args %} |
|||
<li><b>aspect:</b> <code>number</code> - image map aspect ratio.</li> |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return position data having the following structure: |
|||
|
|||
```typescript |
|||
{ |
|||
x: number, |
|||
y: number |
|||
} |
|||
``` |
|||
|
|||
- *x* - new relative x coordinate as double from 0 to 1; |
|||
- *y* - new relative y coordinate as double from 0 to 1; |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
##### Examples |
|||
|
|||
* Scale the coordinates to half the original: |
|||
|
|||
```javascript |
|||
return {x: origXPos / 2, y: origYPos / 2}; |
|||
{:copy-code} |
|||
``` |
|||
|
|||
* Detect markers with same positions and place them with minimum overlap: |
|||
|
|||
```javascript |
|||
var xPos = data.xPos; |
|||
var yPos = data.yPos; |
|||
var locationGroup = dsData.filter((item) => item.xPos === xPos && item.yPos === yPos); |
|||
if (locationGroup.length > 1) { |
|||
const count = locationGroup.length; |
|||
const index = locationGroup.indexOf(data); |
|||
const radius = 0.035; |
|||
const angle = (360 / count) * index - 45; |
|||
const x = xPos + radius * Math.sin(angle*Math.PI/180) / aspect; |
|||
const y = yPos + radius * Math.cos(angle*Math.PI/180); |
|||
return {x: x, y: y}; |
|||
} else { |
|||
return {x: xPos, y: yPos}; |
|||
} |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,40 @@ |
|||
#### Marker tooltip function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData, dsIndex): string* |
|||
|
|||
A JavaScript function used to compute text or HTML code to be displayed in the marker, point or polygon tooltip. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map-legacy/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting text or HTML for the tooltip. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
##### Examples |
|||
|
|||
* Display details with corresponding telemetry data for `thermostat` device type: |
|||
|
|||
```javascript |
|||
var deviceType = data['Type']; |
|||
if (typeof deviceType !== undefined) { |
|||
if (deviceType == "energy meter") { |
|||
return '<b>${entityName}</b><br/><b>Energy:</b> ${energy:2} kWt<br/>'; |
|||
} else if (deviceType == "thermometer") { |
|||
return '<b>${entityName}</b><br/><b>Temperature:</b> ${temperature:2} °C<br/>'; |
|||
} |
|||
} |
|||
return data.entityName; |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,34 @@ |
|||
#### Point as anchor function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData, dsIndex): boolean* |
|||
|
|||
A JavaScript function evaluating whether to use trip point as time anchor used in time selector. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map-legacy/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
`true` if the point should be decided as anchor, `false` otherwise. |
|||
|
|||
In case no data is returned, the point is not used as anchor. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
##### Examples |
|||
|
|||
* Make anchors with 5 seconds step interval: |
|||
|
|||
```javascript |
|||
return data.time % 5000 < 1000; |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,24 @@ |
|||
#### Circle fill color function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData): string* |
|||
|
|||
A JavaScript function used to compute fill color of the circle. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting fill color of the circle. |
|||
|
|||
In case no data is returned, color value from **Color** settings field will be used. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
{% include widget/lib/map/color_fn_examples %} |
|||
@ -0,0 +1,22 @@ |
|||
#### Circle label function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData): string* |
|||
|
|||
A JavaScript function used to compute text or HTML code of the circle label. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting text or HTML of the circle label. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
{% include widget/lib/map/label_fn_examples %} |
|||
@ -0,0 +1,24 @@ |
|||
#### Circle stroke color function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData): string* |
|||
|
|||
A JavaScript function used to compute stroke color of the circle. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting stroke color of the circle. |
|||
|
|||
In case no data is returned, color value from **Color** settings field will be used. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
{% include widget/lib/map/color_fn_examples %} |
|||
@ -0,0 +1,22 @@ |
|||
#### Circle tooltip function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData): string* |
|||
|
|||
A JavaScript function used to compute text or HTML code to be displayed in the circle tooltip. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting text or HTML for the tooltip. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
{% include widget/lib/map/tooltip_fn_examples %} |
|||
@ -0,0 +1,19 @@ |
|||
##### Examples |
|||
|
|||
* Calculate color depending on `temperature` telemetry value for `thermostat` device type: |
|||
|
|||
```javascript |
|||
var type = data.Type; |
|||
if (type == 'thermostat') { |
|||
var temperature = data.temperature; |
|||
if (typeof temperature !== undefined) { |
|||
var percent = (temperature + 60)/120 * 100; |
|||
return tinycolor.mix('blue', 'red', percent).toHexString(); |
|||
} |
|||
return 'blue'; |
|||
} |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
@ -0,0 +1,19 @@ |
|||
##### Examples |
|||
|
|||
* Display styled label with corresponding latest telemetry data for `energy meter` or `thermometer` device types: |
|||
|
|||
```javascript |
|||
var deviceType = data.Type; |
|||
if (typeof deviceType !== undefined) { |
|||
if (deviceType == "energy meter") { |
|||
return '<span style="color:orange;">${entityName}, ${energy:2} kWt</span>'; |
|||
} else if (deviceType == "thermometer") { |
|||
return '<span style="color:blue;">${entityName}, ${temperature:2} °C</span>'; |
|||
} |
|||
} |
|||
return data.entityName; |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
@ -1,10 +1,8 @@ |
|||
<li><b>data:</b> <code><a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts#L108" target="_blank">FormattedData</a></code> - A <a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts#L108" target="_blank">FormattedData</a> object associated with marker or data point of the route.<br/> |
|||
Represents basic entity properties (ex. <code>entityId</code>, <code>entityName</code>)<br/>and provides access to other entity attributes/timeseries declared in widget datasource configuration. |
|||
<li><b>data:</b> <code><a href="https://github.com/thingsboard/thingsboard/blob/b881f1c2985399f9665e033e2479549e97da1f36/ui-ngx/src/app/shared/models/widget.models.ts#L513" target="_blank">FormattedData</a></code> object associated with data layer (markers/polygons/circles) or data point of the route (trips data layer).<br/> |
|||
Represents basic entity properties (ex. <code>entityId</code>, <code>entityName</code>)<br/>and provides access to other entity attributes/timeseries declared in datasource of the data layer configuration. |
|||
</li> |
|||
<li><b>dsData:</b> <code><a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts#L108" target="_blank">FormattedData[]</a></code> - All available data associated with markers or routes data points as array of <a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts#L108" target="_blank">FormattedData</a> objects<br/> |
|||
<li><b>dsData:</b> <code><a href="https://github.com/thingsboard/thingsboard/blob/b881f1c2985399f9665e033e2479549e97da1f36/ui-ngx/src/app/shared/models/widget.models.ts#L513" target="_blank">FormattedData[]</a></code> - All available data associated with data layers including additional datasources as array of <a href="https://github.com/thingsboard/thingsboard/blob/b881f1c2985399f9665e033e2479549e97da1f36/ui-ngx/src/app/shared/models/widget.models.ts#L513" target="_blank">FormattedData</a> objects<br/> |
|||
resolved from configured datasources. Each object represents basic entity properties (ex. <code>entityId</code>, <code>entityName</code>)<br/> |
|||
and provides access to other entity attributes/timeseries declared in widget datasource configuration. |
|||
</li> |
|||
<li><b>dsIndex</b> <code>number</code> - index of the current marker data or route data point in <code>dsData</code> array.<br> |
|||
<strong>Note: </strong> The <code>data</code> argument is equivalent to <code>dsData[dsIndex]</code> expression. |
|||
and provides access to other entity attributes/timeseries declared in datasources of data layers configuration including additional datasources of the map configuration. |
|||
</li> |
|||
|
|||
|
|||
@ -0,0 +1,10 @@ |
|||
<li><b>data:</b> <code><a href="https://github.com/thingsboard/thingsboard/blob/b881f1c2985399f9665e033e2479549e97da1f36/ui-ngx/src/app/shared/models/widget.models.ts#L513" target="_blank">FormattedData</a></code> object associated with data layer (markers/polygons/circles) or data point of the route (trips data layer).<br/> |
|||
Represents basic entity properties (ex. <code>entityId</code>, <code>entityName</code>)<br/>and provides access to other entity attributes/timeseries declared in datasource of the data layer configuration. |
|||
</li> |
|||
<li><b>images:</b> <code>string[]</code> - array of image urls configured in the <b>Marker images</b> section. |
|||
</li> |
|||
<li><b>dsData:</b> <code><a href="https://github.com/thingsboard/thingsboard/blob/b881f1c2985399f9665e033e2479549e97da1f36/ui-ngx/src/app/shared/models/widget.models.ts#L513" target="_blank">FormattedData[]</a></code> - All available data associated with data layers including additional datasources as array of <a href="https://github.com/thingsboard/thingsboard/blob/b881f1c2985399f9665e033e2479549e97da1f36/ui-ngx/src/app/shared/models/widget.models.ts#L513" target="_blank">FormattedData</a> objects<br/> |
|||
resolved from configured datasources. Each object represents basic entity properties (ex. <code>entityId</code>, <code>entityName</code>)<br/> |
|||
and provides access to other entity attributes/timeseries declared in datasources of data layers configuration including additional datasources of the map configuration. |
|||
</li> |
|||
|
|||
@ -0,0 +1,22 @@ |
|||
#### Path point tooltip function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData): string* |
|||
|
|||
A JavaScript function used to compute text or HTML code to be displayed in the trip path point tooltip. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting text or HTML for the tooltip. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
{% include widget/lib/map/tooltip_fn_examples %} |
|||
@ -0,0 +1,24 @@ |
|||
#### Polygon fill color function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData): string* |
|||
|
|||
A JavaScript function used to compute fill color of the polygon. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting fill color of the polygon. |
|||
|
|||
In case no data is returned, color value from **Color** settings field will be used. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
{% include widget/lib/map/color_fn_examples %} |
|||
@ -0,0 +1,22 @@ |
|||
#### Polygon label function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData): string* |
|||
|
|||
A JavaScript function used to compute text or HTML code of the polygon label. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting text or HTML of the polygon label. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
{% include widget/lib/map/label_fn_examples %} |
|||
@ -0,0 +1,24 @@ |
|||
#### Polygon stroke color function |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
*function (data, dsData): string* |
|||
|
|||
A JavaScript function used to compute stroke color of the polygon. |
|||
|
|||
**Parameters:** |
|||
|
|||
<ul> |
|||
{% include widget/lib/map/map_fn_args %} |
|||
</ul> |
|||
|
|||
**Returns:** |
|||
|
|||
Should return string value presenting stroke color of the polygon. |
|||
|
|||
In case no data is returned, color value from **Color** settings field will be used. |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
{% include widget/lib/map/color_fn_examples %} |
|||
@ -0,0 +1,19 @@ |
|||
##### Examples |
|||
|
|||
* Display details with corresponding telemetry data for `energy meter` or `thermometer` device types: |
|||
|
|||
```javascript |
|||
var deviceType = data.Type; |
|||
if (typeof deviceType !== undefined) { |
|||
if (deviceType == "energy meter") { |
|||
return '<b>${entityName}</b><br/><b>Energy:</b> ${energy:2} kWt<br/>'; |
|||
} else if (deviceType == "thermometer") { |
|||
return '<b>${entityName}</b><br/><b>Temperature:</b> ${temperature:2} °C<br/>'; |
|||
} |
|||
} |
|||
return data.entityName; |
|||
{:copy-code} |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
Loading…
Reference in new issue