UI: Improve map widget import/export. Add help assets for new maps.
This commit is contained in:
		
							parent
							
								
									dabd7cca5b
								
							
						
					
					
						commit
						e5b8a24598
					
				@ -16,7 +16,7 @@
 | 
			
		||||
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
import { BreakpointId, Dashboard, DashboardLayoutId } from '@app/shared/models/dashboard.models';
 | 
			
		||||
import { AliasesInfo, EntityAlias, EntityAliases, EntityAliasInfo } from '@shared/models/alias.models';
 | 
			
		||||
import { AliasesInfo, EntityAlias, EntityAliases, EntityAliasInfo, getEntityAliasId } from '@shared/models/alias.models';
 | 
			
		||||
import {
 | 
			
		||||
  Datasource,
 | 
			
		||||
  DatasourceType,
 | 
			
		||||
@ -34,7 +34,8 @@ import { map } from 'rxjs/operators';
 | 
			
		||||
import { FcRuleNode, ruleNodeTypeDescriptors } from '@shared/models/rule-node.models';
 | 
			
		||||
import { RuleChainService } from '@core/http/rule-chain.service';
 | 
			
		||||
import { RuleChainImport } from '@shared/models/rule-chain.models';
 | 
			
		||||
import { Filter, FilterInfo, Filters, FiltersInfo } from '@shared/models/query/query.models';
 | 
			
		||||
import { Filter, FilterInfo, Filters, FiltersInfo, getFilterId } from '@shared/models/query/query.models';
 | 
			
		||||
import { getWidgetExportDefinition } from '@shared/models/widget/widget-export.models';
 | 
			
		||||
 | 
			
		||||
const WIDGET_ITEM = 'widget_item';
 | 
			
		||||
const WIDGET_REFERENCE = 'widget_reference';
 | 
			
		||||
@ -47,6 +48,7 @@ export interface WidgetItem {
 | 
			
		||||
  filtersInfo: FiltersInfo;
 | 
			
		||||
  originalSize: WidgetSize;
 | 
			
		||||
  originalColumns: number;
 | 
			
		||||
  widgetExportInfo?: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface WidgetReference {
 | 
			
		||||
@ -139,12 +141,18 @@ export class ItemBufferService {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    let widgetExportInfo: any;
 | 
			
		||||
    const exportDefinition = getWidgetExportDefinition(widget);
 | 
			
		||||
    if (exportDefinition) {
 | 
			
		||||
      widgetExportInfo = exportDefinition.prepareExportInfo(dashboard, widget);
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
      widget,
 | 
			
		||||
      aliasesInfo,
 | 
			
		||||
      filtersInfo,
 | 
			
		||||
      originalSize,
 | 
			
		||||
      originalColumns
 | 
			
		||||
      originalColumns,
 | 
			
		||||
      widgetExportInfo
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -189,6 +197,7 @@ export class ItemBufferService {
 | 
			
		||||
      const filtersInfo = widgetItem.filtersInfo;
 | 
			
		||||
      const originalColumns = widgetItem.originalColumns;
 | 
			
		||||
      const originalSize = widgetItem.originalSize;
 | 
			
		||||
      const widgetExportInfo = widgetItem.widgetExportInfo;
 | 
			
		||||
      let targetRow = -1;
 | 
			
		||||
      let targetColumn = -1;
 | 
			
		||||
      if (position) {
 | 
			
		||||
@ -199,7 +208,7 @@ export class ItemBufferService {
 | 
			
		||||
      return this.addWidgetToDashboard(targetDashboard, targetState,
 | 
			
		||||
                                targetLayout, widget, aliasesInfo, filtersInfo,
 | 
			
		||||
                                onAliasesUpdateFunction, onFiltersUpdateFunction,
 | 
			
		||||
                                originalColumns, originalSize, targetRow, targetColumn, breakpoint).pipe(
 | 
			
		||||
                                originalColumns, originalSize, targetRow, targetColumn, breakpoint, widgetExportInfo).pipe(
 | 
			
		||||
        map(() => widget)
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
@ -248,7 +257,8 @@ export class ItemBufferService {
 | 
			
		||||
                              originalSize: WidgetSize,
 | 
			
		||||
                              row: number,
 | 
			
		||||
                              column: number,
 | 
			
		||||
                              breakpoint = 'default'): Observable<Dashboard> {
 | 
			
		||||
                              breakpoint = 'default',
 | 
			
		||||
                              widgetExportInfo?: any): Observable<Dashboard> {
 | 
			
		||||
    let theDashboard: Dashboard;
 | 
			
		||||
    if (dashboard) {
 | 
			
		||||
      theDashboard = dashboard;
 | 
			
		||||
@ -258,26 +268,39 @@ export class ItemBufferService {
 | 
			
		||||
    theDashboard = this.dashboardUtils.validateAndUpdateDashboard(theDashboard);
 | 
			
		||||
    let callAliasUpdateFunction = false;
 | 
			
		||||
    let callFilterUpdateFunction = false;
 | 
			
		||||
    let newEntityAliases: EntityAliases;
 | 
			
		||||
    let newFilters: Filters;
 | 
			
		||||
    const exportDefinition = getWidgetExportDefinition(widget);
 | 
			
		||||
    if (exportDefinition && widgetExportInfo || aliasesInfo) {
 | 
			
		||||
      newEntityAliases = deepClone(dashboard.configuration.entityAliases);
 | 
			
		||||
    }
 | 
			
		||||
    if (exportDefinition && widgetExportInfo || filtersInfo) {
 | 
			
		||||
      newFilters = deepClone(dashboard.configuration.filters);
 | 
			
		||||
    }
 | 
			
		||||
    if (aliasesInfo) {
 | 
			
		||||
      const newEntityAliases = this.updateAliases(theDashboard, widget, aliasesInfo);
 | 
			
		||||
      const aliasesUpdated = !isEqual(newEntityAliases, theDashboard.configuration.entityAliases);
 | 
			
		||||
      if (aliasesUpdated) {
 | 
			
		||||
        theDashboard.configuration.entityAliases = newEntityAliases;
 | 
			
		||||
        if (onAliasesUpdateFunction) {
 | 
			
		||||
          callAliasUpdateFunction = true;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      this.updateAliases(widget, newEntityAliases, aliasesInfo);
 | 
			
		||||
    }
 | 
			
		||||
    if (filtersInfo) {
 | 
			
		||||
      const newFilters = this.updateFilters(theDashboard, widget, filtersInfo);
 | 
			
		||||
      const filtersUpdated = !isEqual(newFilters, theDashboard.configuration.filters);
 | 
			
		||||
      if (filtersUpdated) {
 | 
			
		||||
        theDashboard.configuration.filters = newFilters;
 | 
			
		||||
        if (onFiltersUpdateFunction) {
 | 
			
		||||
          callFilterUpdateFunction = true;
 | 
			
		||||
        }
 | 
			
		||||
      this.updateFilters(widget, newFilters, filtersInfo);
 | 
			
		||||
    }
 | 
			
		||||
    if (exportDefinition && widgetExportInfo) {
 | 
			
		||||
      exportDefinition.updateFromExportInfo(widget, newEntityAliases, newFilters, widgetExportInfo);
 | 
			
		||||
    }
 | 
			
		||||
    const aliasesUpdated = newEntityAliases && !isEqual(newEntityAliases, theDashboard.configuration.entityAliases);
 | 
			
		||||
    if (aliasesUpdated) {
 | 
			
		||||
      theDashboard.configuration.entityAliases = newEntityAliases;
 | 
			
		||||
      if (onAliasesUpdateFunction) {
 | 
			
		||||
        callAliasUpdateFunction = true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    const filtersUpdated = newFilters && !isEqual(newFilters, theDashboard.configuration.filters);
 | 
			
		||||
    if (filtersUpdated) {
 | 
			
		||||
      theDashboard.configuration.filters = newFilters;
 | 
			
		||||
      if (onFiltersUpdateFunction) {
 | 
			
		||||
        callFilterUpdateFunction = true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.dashboardUtils.addWidgetToLayout(theDashboard, targetState, targetLayout, widget,
 | 
			
		||||
                                          originalColumns, originalSize, row, column, breakpoint);
 | 
			
		||||
    if (callAliasUpdateFunction) {
 | 
			
		||||
@ -430,14 +453,13 @@ export class ItemBufferService {
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private updateAliases(dashboard: Dashboard, widget: Widget, aliasesInfo: AliasesInfo): EntityAliases {
 | 
			
		||||
    const entityAliases = deepClone(dashboard.configuration.entityAliases);
 | 
			
		||||
  private updateAliases(widget: Widget, entityAliases: EntityAliases, aliasesInfo: AliasesInfo): void {
 | 
			
		||||
    let aliasInfo: EntityAliasInfo;
 | 
			
		||||
    let newAliasId: string;
 | 
			
		||||
    for (const datasourceIndexStr of Object.keys(aliasesInfo.datasourceAliases)) {
 | 
			
		||||
      const datasourceIndex = Number(datasourceIndexStr);
 | 
			
		||||
      aliasInfo = aliasesInfo.datasourceAliases[datasourceIndex];
 | 
			
		||||
      newAliasId = this.getEntityAliasId(entityAliases, aliasInfo);
 | 
			
		||||
      newAliasId = getEntityAliasId(entityAliases, aliasInfo);
 | 
			
		||||
      if (widget.type === widgetType.alarm) {
 | 
			
		||||
        widget.config.alarmSource.entityAliasId = newAliasId;
 | 
			
		||||
      } else {
 | 
			
		||||
@ -446,7 +468,7 @@ export class ItemBufferService {
 | 
			
		||||
    }
 | 
			
		||||
    if (aliasesInfo.targetDeviceAlias) {
 | 
			
		||||
      aliasInfo = aliasesInfo.targetDeviceAlias;
 | 
			
		||||
      newAliasId = this.getEntityAliasId(entityAliases, aliasInfo);
 | 
			
		||||
      newAliasId = getEntityAliasId(entityAliases, aliasInfo);
 | 
			
		||||
      if (widget.config.targetDevice?.type !== TargetDeviceType.entity) {
 | 
			
		||||
        widget.config.targetDevice = {
 | 
			
		||||
          type: TargetDeviceType.entity
 | 
			
		||||
@ -454,101 +476,21 @@ export class ItemBufferService {
 | 
			
		||||
      }
 | 
			
		||||
      widget.config.targetDevice.entityAliasId = newAliasId;
 | 
			
		||||
    }
 | 
			
		||||
    return entityAliases;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private updateFilters(dashboard: Dashboard, widget: Widget, filtersInfo: FiltersInfo): Filters {
 | 
			
		||||
    const filters = deepClone(dashboard.configuration.filters);
 | 
			
		||||
  private updateFilters(widget: Widget, filters: Filters, filtersInfo: FiltersInfo): void {
 | 
			
		||||
    let filterInfo: FilterInfo;
 | 
			
		||||
    let newFilterId: string;
 | 
			
		||||
    for (const datasourceIndexStr of Object.keys(filtersInfo.datasourceFilters)) {
 | 
			
		||||
      const datasourceIndex = Number(datasourceIndexStr);
 | 
			
		||||
      filterInfo = filtersInfo.datasourceFilters[datasourceIndex];
 | 
			
		||||
      newFilterId = this.getFilterId(filters, filterInfo);
 | 
			
		||||
      newFilterId = getFilterId(filters, filterInfo);
 | 
			
		||||
      if (widget.type === widgetType.alarm) {
 | 
			
		||||
        widget.config.alarmSource.filterId = newFilterId;
 | 
			
		||||
      } else {
 | 
			
		||||
        widget.config.datasources[datasourceIndex].filterId = newFilterId;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return filters;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private isEntityAliasEqual(alias1: EntityAliasInfo, alias2: EntityAliasInfo): boolean {
 | 
			
		||||
    return isEqual(alias1.filter, alias2.filter);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private getEntityAliasId(entityAliases: EntityAliases, aliasInfo: EntityAliasInfo): string {
 | 
			
		||||
    let newAliasId: string;
 | 
			
		||||
    for (const aliasId of Object.keys(entityAliases)) {
 | 
			
		||||
      if (this.isEntityAliasEqual(entityAliases[aliasId], aliasInfo)) {
 | 
			
		||||
        newAliasId = aliasId;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (!newAliasId) {
 | 
			
		||||
      const newAliasName = this.createEntityAliasName(entityAliases, aliasInfo.alias);
 | 
			
		||||
      newAliasId = this.utils.guid();
 | 
			
		||||
      entityAliases[newAliasId] = {id: newAliasId, alias: newAliasName, filter: aliasInfo.filter};
 | 
			
		||||
    }
 | 
			
		||||
    return newAliasId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private createEntityAliasName(entityAliases: EntityAliases, alias: string): string {
 | 
			
		||||
    let c = 0;
 | 
			
		||||
    let newAlias = alias;
 | 
			
		||||
    let unique = false;
 | 
			
		||||
    while (!unique) {
 | 
			
		||||
      unique = true;
 | 
			
		||||
      for (const entAliasId of Object.keys(entityAliases)) {
 | 
			
		||||
        const entAlias = entityAliases[entAliasId];
 | 
			
		||||
        if (newAlias === entAlias.alias) {
 | 
			
		||||
          c++;
 | 
			
		||||
          newAlias = alias + c;
 | 
			
		||||
          unique = false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return newAlias;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private isFilterEqual(filter1: FilterInfo, filter2: FilterInfo): boolean {
 | 
			
		||||
    return isEqual(filter1.keyFilters, filter2.keyFilters);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private getFilterId(filters: Filters, filterInfo: FilterInfo): string {
 | 
			
		||||
    let newFilterId: string;
 | 
			
		||||
    for (const filterId of Object.keys(filters)) {
 | 
			
		||||
      if (this.isFilterEqual(filters[filterId], filterInfo)) {
 | 
			
		||||
        newFilterId = filterId;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (!newFilterId) {
 | 
			
		||||
      const newFilterName = this.createFilterName(filters, filterInfo.filter);
 | 
			
		||||
      newFilterId = this.utils.guid();
 | 
			
		||||
      filters[newFilterId] = {id: newFilterId, filter: newFilterName,
 | 
			
		||||
        keyFilters: filterInfo.keyFilters, editable: filterInfo.editable};
 | 
			
		||||
    }
 | 
			
		||||
    return newFilterId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private createFilterName(filters: Filters, filter: string): string {
 | 
			
		||||
    let c = 0;
 | 
			
		||||
    let newFilter = filter;
 | 
			
		||||
    let unique = false;
 | 
			
		||||
    while (!unique) {
 | 
			
		||||
      unique = true;
 | 
			
		||||
      for (const entFilterId of Object.keys(filters)) {
 | 
			
		||||
        const entFilter = filters[entFilterId];
 | 
			
		||||
        if (newFilter === entFilter.filter) {
 | 
			
		||||
          c++;
 | 
			
		||||
          newFilter = filter + c;
 | 
			
		||||
          unique = false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return newFilter;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private storeSet(key: string, elem: any) {
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@ import {
 | 
			
		||||
  isJSON, MapDataLayerType,
 | 
			
		||||
  TbCircleData,
 | 
			
		||||
  TbMapDatasource
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import L from 'leaflet';
 | 
			
		||||
import { FormattedData } from '@shared/models/widget.models';
 | 
			
		||||
import { TbShapesDataLayer } from '@home/components/widget/lib/maps/data-layer/shapes-data-layer';
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@ import {
 | 
			
		||||
  DataLayerTooltipSettings,
 | 
			
		||||
  DataLayerTooltipTrigger, processTooltipTemplate,
 | 
			
		||||
  TbMapDatasource
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { TbMap } from '@home/components/widget/lib/maps/map';
 | 
			
		||||
import { FormattedData } from '@shared/models/widget.models';
 | 
			
		||||
import L from 'leaflet';
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@ import {
 | 
			
		||||
  DataLayerEditAction,
 | 
			
		||||
  MapDataLayerSettings,
 | 
			
		||||
  TbMapDatasource
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { TbMap } from '@home/components/widget/lib/maps/map';
 | 
			
		||||
import { FormattedData, WidgetActionType } from '@shared/models/widget.models';
 | 
			
		||||
import { Observable } from 'rxjs';
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@ import {
 | 
			
		||||
  MapDataLayerSettings, MapDataLayerType, mapDataSourceSettingsToDatasource,
 | 
			
		||||
  MapStringFunction, MapType,
 | 
			
		||||
  TbMapDatasource
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import {
 | 
			
		||||
  createLabelFromPattern,
 | 
			
		||||
  guid, isDefined,
 | 
			
		||||
@ -82,6 +82,7 @@ export class DataLayerColorProcessor {
 | 
			
		||||
              private settings: DataLayerColorSettings) {}
 | 
			
		||||
 | 
			
		||||
  public setup(): Observable<void> {
 | 
			
		||||
    this.color = this.settings.color;
 | 
			
		||||
    if (this.settings.type === DataLayerColorType.function) {
 | 
			
		||||
      return parseTbFunction<MapStringFunction>(this.dataLayer.getCtx().http, this.settings.colorFunction, ['data', 'dsData']).pipe(
 | 
			
		||||
        map((parsed) => {
 | 
			
		||||
@ -90,7 +91,6 @@ export class DataLayerColorProcessor {
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
      this.color = this.settings.color;
 | 
			
		||||
      return of(null)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -99,6 +99,9 @@ export class DataLayerColorProcessor {
 | 
			
		||||
    let color: string;
 | 
			
		||||
    if (this.settings.type === DataLayerColorType.function) {
 | 
			
		||||
      color = safeExecuteTbFunction(this.colorFunction, [data, dsData]);
 | 
			
		||||
      if (!color) {
 | 
			
		||||
        color = this.color;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      color = this.color;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,7 @@ import {
 | 
			
		||||
  MarkerShapeSettings,
 | 
			
		||||
  MarkerType,
 | 
			
		||||
  TbMapDatasource
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import L, { FeatureGroup } from 'leaflet';
 | 
			
		||||
import { FormattedData } from '@shared/models/widget.models';
 | 
			
		||||
import { forkJoin, Observable, of } from 'rxjs';
 | 
			
		||||
@ -55,7 +55,7 @@ import {
 | 
			
		||||
  createColorMarkerIconElement,
 | 
			
		||||
  createColorMarkerShapeURI,
 | 
			
		||||
  MarkerShape
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/marker-shape.models';
 | 
			
		||||
} from '@shared/models/widget/maps/marker-shape.models';
 | 
			
		||||
import { MatIconRegistry } from '@angular/material/icon';
 | 
			
		||||
import { DomSanitizer } from '@angular/platform-browser';
 | 
			
		||||
import {
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ import {
 | 
			
		||||
  isCutPolygon, isJSON, MapDataLayerType,
 | 
			
		||||
  PolygonsDataLayerSettings,
 | 
			
		||||
  TbMapDatasource, TbPolyData, TbPolygonCoordinates, TbPolygonRawCoordinates
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import L from 'leaflet';
 | 
			
		||||
import { FormattedData } from '@shared/models/widget.models';
 | 
			
		||||
import { TbShapesDataLayer } from '@home/components/widget/lib/maps/data-layer/shapes-data-layer';
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@
 | 
			
		||||
/// limitations under the License.
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
import { ShapeDataLayerSettings, TbMapDatasource } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { ShapeDataLayerSettings, TbMapDatasource } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import L from 'leaflet';
 | 
			
		||||
import { TbMap } from '@home/components/widget/lib/maps/map';
 | 
			
		||||
import { forkJoin, Observable } from 'rxjs';
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,7 @@ import {
 | 
			
		||||
  MapDataLayerType,
 | 
			
		||||
  TbMapDatasource,
 | 
			
		||||
  TripsDataLayerSettings
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { forkJoin, Observable } from 'rxjs';
 | 
			
		||||
import { FormattedData, WidgetActionType } from '@shared/models/widget.models';
 | 
			
		||||
import { map } from 'rxjs/operators';
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@ import {
 | 
			
		||||
  TbPolygonCoordinates,
 | 
			
		||||
  TbPolygonRawCoordinate,
 | 
			
		||||
  TbPolygonRawCoordinates
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { WidgetContext } from '@home/models/widget-component.models';
 | 
			
		||||
import { DeepPartial } from '@shared/models/common';
 | 
			
		||||
import { forkJoin, Observable, of } from 'rxjs';
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ import {
 | 
			
		||||
  loadImageWithAspect,
 | 
			
		||||
  MapZoomAction,
 | 
			
		||||
  TbCircleData, TbPolygonCoordinate, TbPolygonCoordinates, TbPolygonRawCoordinate, TbPolygonRawCoordinates
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { WidgetContext } from '@home/models/widget-component.models';
 | 
			
		||||
import { DeepPartial } from '@shared/models/common';
 | 
			
		||||
import { Observable, of, ReplaySubject, switchMap } from 'rxjs';
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ import {
 | 
			
		||||
  MapProvider,
 | 
			
		||||
  OpenStreetMapLayerSettings,
 | 
			
		||||
  TencentMapLayerSettings
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { WidgetContext } from '@home/models/widget-component.models';
 | 
			
		||||
import { DeepPartial } from '@shared/models/common';
 | 
			
		||||
import { mergeDeep } from '@core/utils';
 | 
			
		||||
 | 
			
		||||
@ -15,14 +15,12 @@
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  AfterViewInit,
 | 
			
		||||
  ChangeDetectorRef,
 | 
			
		||||
  Component,
 | 
			
		||||
  ElementRef,
 | 
			
		||||
  Input,
 | 
			
		||||
  OnDestroy,
 | 
			
		||||
  OnInit,
 | 
			
		||||
  Renderer2,
 | 
			
		||||
  TemplateRef,
 | 
			
		||||
  ViewChild,
 | 
			
		||||
  ViewEncapsulation
 | 
			
		||||
@ -36,7 +34,7 @@ import { WidgetContext } from '@home/models/widget-component.models';
 | 
			
		||||
import { Observable } from 'rxjs';
 | 
			
		||||
import { backgroundStyle, ComponentStyle, overlayStyle } from '@shared/models/widget-settings.models';
 | 
			
		||||
import { TbMap } from '@home/components/widget/lib/maps/map';
 | 
			
		||||
import { MapSetting } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { MapSetting } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { WidgetComponent } from '@home/components/widget/widget.component';
 | 
			
		||||
import { ImagePipe } from '@shared/pipe/image.pipe';
 | 
			
		||||
import { DomSanitizer } from '@angular/platform-browser';
 | 
			
		||||
@ -69,7 +67,6 @@ export class MapWidgetComponent implements OnInit, OnDestroy {
 | 
			
		||||
  constructor(public widgetComponent: WidgetComponent,
 | 
			
		||||
              private imagePipe: ImagePipe,
 | 
			
		||||
              private sanitizer: DomSanitizer,
 | 
			
		||||
              private renderer: Renderer2,
 | 
			
		||||
              private cd: ChangeDetectorRef) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@
 | 
			
		||||
/// limitations under the License.
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
import { defaultMapSettings, MapSetting, MapType } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { defaultMapSettings, MapSetting, MapType } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { BackgroundSettings, BackgroundType } from '@shared/models/widget-settings.models';
 | 
			
		||||
import { mergeDeep } from '@core/utils';
 | 
			
		||||
import { WidgetContext } from '@home/models/widget-component.models';
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ import {
 | 
			
		||||
  TbMapDatasource,
 | 
			
		||||
  TbPolygonCoordinates,
 | 
			
		||||
  TbPolygonRawCoordinates
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { WidgetContext } from '@home/models/widget-component.models';
 | 
			
		||||
import {
 | 
			
		||||
  formattedDataArrayFromDatasourceData,
 | 
			
		||||
@ -63,7 +63,7 @@ import {
 | 
			
		||||
  SelectMapEntityPanelComponent
 | 
			
		||||
} from '@home/components/widget/lib/maps/panels/select-map-entity-panel.component';
 | 
			
		||||
import { TbPopoverComponent } from '@shared/components/popover.component';
 | 
			
		||||
import { createPlaceItemIcon } from '@home/components/widget/lib/maps/models/marker-shape.models';
 | 
			
		||||
import { createPlaceItemIcon } from '@shared/models/widget/maps/marker-shape.models';
 | 
			
		||||
import { MatIconRegistry } from '@angular/material/icon';
 | 
			
		||||
import { DomSanitizer } from '@angular/platform-browser';
 | 
			
		||||
import { MapTimelinePanelComponent } from '@home/components/widget/lib/maps/panels/map-timeline-panel.component';
 | 
			
		||||
@ -464,7 +464,7 @@ export abstract class TbMap<S extends BaseMapSettings> {
 | 
			
		||||
     }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private toggleDragMode(e: MouseEvent, button: L.TB.ToolbarButton): void {
 | 
			
		||||
  private toggleDragMode(_e: MouseEvent, button: L.TB.ToolbarButton): void {
 | 
			
		||||
    if (this.dragMode) {
 | 
			
		||||
      this.disableDragMode();
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@ import {
 | 
			
		||||
  Output,
 | 
			
		||||
  ViewEncapsulation
 | 
			
		||||
} from '@angular/core';
 | 
			
		||||
import { TripTimelineSettings } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { TripTimelineSettings } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { DateFormatProcessor } from '@shared/models/widget-settings.models';
 | 
			
		||||
import { interval, Subscription } from 'rxjs';
 | 
			
		||||
import { filter } from 'rxjs/operators';
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,7 @@
 | 
			
		||||
                [functionArgs]="['data', 'dsData']"
 | 
			
		||||
                [globalVariables]="functionScopeVariables"
 | 
			
		||||
                functionTitle="{{ 'widgets.maps.data-layer.color-function' | translate }}"
 | 
			
		||||
                helpId="widget/lib/map/color_fn">
 | 
			
		||||
                [helpId]="helpId">
 | 
			
		||||
    </tb-js-func>
 | 
			
		||||
  </div>
 | 
			
		||||
</ng-template>
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@ import { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@core/core.state';
 | 
			
		||||
import { WidgetService } from '@core/http/widget.service';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import { DataLayerColorSettings, DataLayerColorType } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { DataLayerColorSettings, DataLayerColorType } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'tb-data-layer-color-settings-panel',
 | 
			
		||||
@ -36,6 +36,9 @@ export class DataLayerColorSettingsPanelComponent extends PageComponent implemen
 | 
			
		||||
  @Input()
 | 
			
		||||
  colorSettings: DataLayerColorSettings;
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  helpId = 'widget/lib/map/color_fn';
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  popover: TbPopoverComponent<DataLayerColorSettingsPanelComponent>;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
 | 
			
		||||
import { ComponentStyle } from '@shared/models/widget-settings.models';
 | 
			
		||||
import { MatButton } from '@angular/material/button';
 | 
			
		||||
import { TbPopoverService } from '@shared/components/popover.service';
 | 
			
		||||
import { DataLayerColorSettings, DataLayerColorType } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { DataLayerColorSettings, DataLayerColorType } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import {
 | 
			
		||||
  DataLayerColorSettingsPanelComponent
 | 
			
		||||
} from '@home/components/widget/lib/settings/common/map/data-layer-color-settings-panel.component';
 | 
			
		||||
@ -41,6 +41,9 @@ export class DataLayerColorSettingsComponent implements ControlValueAccessor {
 | 
			
		||||
  @Input()
 | 
			
		||||
  disabled: boolean;
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  helpId = 'widget/lib/map/color_fn';
 | 
			
		||||
 | 
			
		||||
  DataLayerColorType = DataLayerColorType;
 | 
			
		||||
 | 
			
		||||
  modelValue: DataLayerColorSettings;
 | 
			
		||||
@ -82,6 +85,7 @@ export class DataLayerColorSettingsComponent implements ControlValueAccessor {
 | 
			
		||||
    } else {
 | 
			
		||||
      const ctx: any = {
 | 
			
		||||
        colorSettings: this.modelValue,
 | 
			
		||||
        helpId: this.helpId
 | 
			
		||||
      };
 | 
			
		||||
      const colorSettingsPanelPopover = this.popoverService.displayPopover(trigger, this.renderer,
 | 
			
		||||
        this.viewContainerRef, DataLayerColorSettingsPanelComponent, 'left', true, null,
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,7 @@
 | 
			
		||||
                    [globalVariables]="functionScopeVariables"
 | 
			
		||||
                    [functionArgs]="['data', 'dsData']"
 | 
			
		||||
                    functionTitle="{{ (patternType === 'label' ? 'widgets.maps.data-layer.label-function' : 'widgets.maps.data-layer.tooltip-function') | translate }}"
 | 
			
		||||
                    helpId="{{ patternType === 'label' ? 'widget/lib/map/label_fn' : 'widget/lib/map/tooltip_fn' }}">
 | 
			
		||||
                    [helpId]="helpId">
 | 
			
		||||
        </tb-js-func>
 | 
			
		||||
        <ng-container *ngIf="patternType === 'tooltip'">
 | 
			
		||||
          <div class="tb-form-row space-between column-xs">
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@ import {
 | 
			
		||||
  DataLayerPatternSettings,
 | 
			
		||||
  DataLayerPatternType,
 | 
			
		||||
  DataLayerTooltipSettings, dataLayerTooltipTriggers, dataLayerTooltipTriggerTranslationMap
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { coerceBoolean } from '@shared/decorators/coercion';
 | 
			
		||||
import { MapSettingsContext } from '@home/components/widget/lib/settings/common/map/map-settings.component.models';
 | 
			
		||||
 | 
			
		||||
@ -71,6 +71,9 @@ export class DataLayerPatternSettingsComponent implements OnInit, ControlValueAc
 | 
			
		||||
  @Input()
 | 
			
		||||
  patternType: 'label' | 'tooltip' = 'label';
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  helpId = 'widget/lib/map/label_fn';
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  patternTitle: string;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@
 | 
			
		||||
/// limitations under the License.
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
import { Component, DestroyRef, forwardRef, Input, OnInit, ViewEncapsulation } from '@angular/core';
 | 
			
		||||
import { Component, DestroyRef, forwardRef, Input, OnInit } from '@angular/core';
 | 
			
		||||
import {
 | 
			
		||||
  ControlValueAccessor,
 | 
			
		||||
  NG_VALIDATORS,
 | 
			
		||||
@ -26,7 +26,7 @@ import {
 | 
			
		||||
  Validators
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import { ImageMapSourceSettings, ImageSourceType } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { ImageMapSourceSettings, ImageSourceType } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { DataKey, DatasourceType, widgetType } from '@shared/models/widget.models';
 | 
			
		||||
import { MapSettingsContext } from '@home/components/widget/lib/settings/common/map/map-settings.component.models';
 | 
			
		||||
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ import {
 | 
			
		||||
  ValidationErrors,
 | 
			
		||||
  Validator
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { MapActionButtonSettings } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { MapActionButtonSettings } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { WidgetAction, WidgetActionType, widgetType } from '@shared/models/widget.models';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import { isEmptyStr } from '@core/utils';
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,7 @@ import {
 | 
			
		||||
import {
 | 
			
		||||
  defaultMapActionButtonSettings,
 | 
			
		||||
  MapActionButtonSettings
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { CdkDragDrop } from '@angular/cdk/drag-drop';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -256,7 +256,7 @@
 | 
			
		||||
                    <input matInput type="number" min="0" formControlName="pathStrokeWeight" placeholder="{{ 'widget-config.set' | translate }}">
 | 
			
		||||
                    <span matSuffix>px</span>
 | 
			
		||||
                  </mat-form-field>
 | 
			
		||||
                  <tb-data-layer-color-settings formControlName="pathStrokeColor"></tb-data-layer-color-settings>
 | 
			
		||||
                  <tb-data-layer-color-settings helpId="widget/lib/map/path_color_fn" formControlName="pathStrokeColor"></tb-data-layer-color-settings>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="tb-form-panel tb-slide-toggle stroked">
 | 
			
		||||
@ -334,13 +334,14 @@
 | 
			
		||||
                    <input matInput type="number" min="0" formControlName="pointSize" placeholder="{{ 'widget-config.set' | translate }}">
 | 
			
		||||
                    <span matSuffix>px</span>
 | 
			
		||||
                  </mat-form-field>
 | 
			
		||||
                  <tb-data-layer-color-settings formControlName="pointColor"></tb-data-layer-color-settings>
 | 
			
		||||
                  <tb-data-layer-color-settings helpId="widget/lib/map/path_point_color_fn" formControlName="pointColor"></tb-data-layer-color-settings>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <tb-data-layer-pattern-settings
 | 
			
		||||
                patternType="tooltip"
 | 
			
		||||
                patternTitle="{{ 'widgets.maps.data-layer.points.point-tooltip' | translate }}"
 | 
			
		||||
                [context]="context"
 | 
			
		||||
                helpId="widget/lib/map/path_point_tooltip_fn"
 | 
			
		||||
                formControlName="pointTooltip">
 | 
			
		||||
              </tb-data-layer-pattern-settings>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
@ -350,7 +351,7 @@
 | 
			
		||||
      <ng-container *ngIf="['polygons', 'circles'].includes(dataLayerType)">
 | 
			
		||||
        <div class="tb-form-row space-between">
 | 
			
		||||
          <div translate>widgets.maps.data-layer.fill-color</div>
 | 
			
		||||
          <tb-data-layer-color-settings formControlName="fillColor"></tb-data-layer-color-settings>
 | 
			
		||||
          <tb-data-layer-color-settings helpId="{{ dataLayerType === 'polygons' ? 'widget/lib/map/polygon_fill_color_fn' : 'widget/lib/map/circle_fill_color_fn' }}" formControlName="fillColor"></tb-data-layer-color-settings>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="tb-form-row space-between">
 | 
			
		||||
          <div translate>widgets.maps.data-layer.stroke</div>
 | 
			
		||||
@ -359,18 +360,20 @@
 | 
			
		||||
              <input matInput type="number" min="0" formControlName="strokeWeight" placeholder="{{ 'widget-config.set' | translate }}">
 | 
			
		||||
              <span matSuffix>px</span>
 | 
			
		||||
            </mat-form-field>
 | 
			
		||||
            <tb-data-layer-color-settings formControlName="strokeColor"></tb-data-layer-color-settings>
 | 
			
		||||
            <tb-data-layer-color-settings helpId="{{ dataLayerType === 'polygons' ? 'widget/lib/map/polygon_stroke_color_fn' : 'widget/lib/map/circle_stroke_color_fn' }}" formControlName="strokeColor"></tb-data-layer-color-settings>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </ng-container>
 | 
			
		||||
      <tb-data-layer-pattern-settings
 | 
			
		||||
        patternType="label"
 | 
			
		||||
        [context]="context"
 | 
			
		||||
        [helpId]="labelHelpId"
 | 
			
		||||
        formControlName="label">
 | 
			
		||||
      </tb-data-layer-pattern-settings>
 | 
			
		||||
      <tb-data-layer-pattern-settings
 | 
			
		||||
        patternType="tooltip"
 | 
			
		||||
        [context]="context"
 | 
			
		||||
        [helpId]="tooltipHelpId"
 | 
			
		||||
        [hasTooltipOffset]="['trips', 'markers'].includes(dataLayerType)"
 | 
			
		||||
        formControlName="tooltip">
 | 
			
		||||
      </tb-data-layer-pattern-settings>
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,7 @@ import {
 | 
			
		||||
  MarkerType, pathDecoratorSymbols, pathDecoratorSymbolTranslationMap,
 | 
			
		||||
  PolygonsDataLayerSettings,
 | 
			
		||||
  ShapeDataLayerSettings, TripsDataLayerSettings
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@core/core.state';
 | 
			
		||||
import { Router } from '@angular/router';
 | 
			
		||||
@ -94,6 +94,36 @@ export class MapDataLayerDialogComponent extends DialogComponent<MapDataLayerDia
 | 
			
		||||
 | 
			
		||||
  dialogTitle: string;
 | 
			
		||||
 | 
			
		||||
  get labelHelpId(): string {
 | 
			
		||||
    switch (this.dataLayerType) {
 | 
			
		||||
      case 'trips':
 | 
			
		||||
        return 'widget/lib/map/label_fn';
 | 
			
		||||
      case 'markers':
 | 
			
		||||
        return 'widget/lib/map/label_fn';
 | 
			
		||||
      case 'polygons':
 | 
			
		||||
        return 'widget/lib/map/polygon_label_fn';
 | 
			
		||||
      case 'circles':
 | 
			
		||||
        return 'widget/lib/map/circle_label_fn';
 | 
			
		||||
      default:
 | 
			
		||||
        return 'widget/lib/map/label_fn';
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get tooltipHelpId(): string {
 | 
			
		||||
    switch (this.dataLayerType) {
 | 
			
		||||
      case 'trips':
 | 
			
		||||
        return 'widget/lib/map/tooltip_fn';
 | 
			
		||||
      case 'markers':
 | 
			
		||||
        return 'widget/lib/map/tooltip_fn';
 | 
			
		||||
      case 'polygons':
 | 
			
		||||
        return 'widget/lib/map/polygon_tooltip_fn';
 | 
			
		||||
      case 'circles':
 | 
			
		||||
        return 'widget/lib/map/circle_tooltip_fn';
 | 
			
		||||
      default:
 | 
			
		||||
        return 'widget/lib/map/tooltip_fn';
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  constructor(protected store: Store<AppState>,
 | 
			
		||||
              protected router: Router,
 | 
			
		||||
              @Inject(MAT_DIALOG_DATA) public data: MapDataLayerDialogData,
 | 
			
		||||
 | 
			
		||||
@ -42,7 +42,7 @@ import {
 | 
			
		||||
  MarkersDataLayerSettings,
 | 
			
		||||
  PolygonsDataLayerSettings,
 | 
			
		||||
  TripsDataLayerSettings
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { DataKey, DatasourceType, datasourceTypeTranslationMap, widgetType } from '@shared/models/widget.models';
 | 
			
		||||
import { EntityType } from '@shared/models/entity-type.models';
 | 
			
		||||
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ import {
 | 
			
		||||
  mapDataLayerValid,
 | 
			
		||||
  mapDataLayerValidator,
 | 
			
		||||
  MapType
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { MapSettingsComponent } from '@home/components/widget/lib/settings/common/map/map-settings.component';
 | 
			
		||||
import { MapSettingsContext } from '@home/components/widget/lib/settings/common/map/map-settings.component.models';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,7 @@ import {
 | 
			
		||||
  Validators
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import { AdditionalMapDataSourceSettings } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { AdditionalMapDataSourceSettings } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { DataKey, DatasourceType, datasourceTypeTranslationMap, widgetType } from '@shared/models/widget.models';
 | 
			
		||||
import { EntityType } from '@shared/models/entity-type.models';
 | 
			
		||||
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,7 @@ import {
 | 
			
		||||
  additionalMapDataSourceValid,
 | 
			
		||||
  additionalMapDataSourceValidator,
 | 
			
		||||
  defaultAdditionalMapDataSourceSettings
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { MapSettingsContext } from '@home/components/widget/lib/settings/common/map/map-settings.component.models';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
 | 
			
		||||
@ -53,7 +53,7 @@ import {
 | 
			
		||||
  openStreetMapLayerTranslationMap,
 | 
			
		||||
  tencentLayerTranslationMap,
 | 
			
		||||
  tencentLayerTypes
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { deepClone } from '@core/utils';
 | 
			
		||||
import {
 | 
			
		||||
  MapLayerSettingsPanelComponent
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,7 @@ import {
 | 
			
		||||
  openStreetMapLayerTranslationMap,
 | 
			
		||||
  tencentLayerTranslationMap,
 | 
			
		||||
  tencentLayerTypes
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { TranslateService } from '@ngx-translate/core';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ import {
 | 
			
		||||
  mapLayerValid,
 | 
			
		||||
  mapLayerValidator,
 | 
			
		||||
  MapProvider
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'tb-map-layers',
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,7 @@ import {
 | 
			
		||||
  MapType,
 | 
			
		||||
  mapZoomActions,
 | 
			
		||||
  mapZoomActionTranslationMap
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import { merge, Observable } from 'rxjs';
 | 
			
		||||
import { coerceBoolean } from '@shared/decorators/coercion';
 | 
			
		||||
@ -254,7 +254,6 @@ export class MapSettingsComponent implements OnInit, ControlValueAccessor, Valid
 | 
			
		||||
 | 
			
		||||
  private updateDragButtonModeSettings() {
 | 
			
		||||
    const markers: MapDataLayerSettings[] = this.mapSettingsFormGroup.get('markers').value;
 | 
			
		||||
    const circles: MapDataLayerSettings[] = this.mapSettingsFormGroup.get('circles').value;
 | 
			
		||||
    let dragModeButtonSettingsEnabled = markers.some(d => d.edit && d.edit.enabledActions && d.edit.enabledActions.includes(DataLayerEditAction.move));
 | 
			
		||||
    if (!dragModeButtonSettingsEnabled) {
 | 
			
		||||
      const polygons: MapDataLayerSettings[] = this.mapSettingsFormGroup.get('polygons').value;
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ import {
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { WidgetService } from '@core/http/widget.service';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import { MarkerClusteringSettings } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { MarkerClusteringSettings } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { merge } from 'rxjs';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@ import { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@core/core.state';
 | 
			
		||||
import { WidgetService } from '@core/http/widget.service';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import { MarkerImageSettings, MarkerImageType } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { MarkerImageSettings, MarkerImageType } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'tb-marker-image-settings-panel',
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@ import { ChangeDetectorRef, Component, forwardRef, Input, Renderer2, ViewContain
 | 
			
		||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
 | 
			
		||||
import { MatButton } from '@angular/material/button';
 | 
			
		||||
import { TbPopoverService } from '@shared/components/popover.service';
 | 
			
		||||
import { MarkerImageSettings, MarkerImageType } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { MarkerImageSettings, MarkerImageType } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import {
 | 
			
		||||
  MarkerImageSettingsPanelComponent
 | 
			
		||||
} from '@home/components/widget/lib/settings/common/map/marker-image-settings-panel.component';
 | 
			
		||||
 | 
			
		||||
@ -30,5 +30,5 @@
 | 
			
		||||
    <div *ngIf="markerType === MarkerType.icon" matButtonIcon style="object-fit: contain; width: 24px; height: 24px;" [innerHTML]="iconPreview$ | async" [class.disabled]="disabled">
 | 
			
		||||
    </div>
 | 
			
		||||
  </button>
 | 
			
		||||
  <tb-data-layer-color-settings formControlName="color"></tb-data-layer-color-settings>
 | 
			
		||||
  <tb-data-layer-color-settings helpId="widget/lib/map/color_fn" formControlName="color"></tb-data-layer-color-settings>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,7 @@ import {
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { MatButton } from '@angular/material/button';
 | 
			
		||||
import { TbPopoverService } from '@shared/components/popover.service';
 | 
			
		||||
import { MarkerIconSettings, MarkerShapeSettings, MarkerType } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { MarkerIconSettings, MarkerShapeSettings, MarkerType } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import { Observable } from 'rxjs';
 | 
			
		||||
import { DomSanitizer, SafeHtml, SafeUrl } from '@angular/platform-browser';
 | 
			
		||||
@ -41,7 +41,7 @@ import { MatIconRegistry } from '@angular/material/icon';
 | 
			
		||||
import {
 | 
			
		||||
  createColorMarkerIconElement,
 | 
			
		||||
  createColorMarkerShapeURI
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/marker-shape.models';
 | 
			
		||||
} from '@shared/models/widget/maps/marker-shape.models';
 | 
			
		||||
import tinycolor from 'tinycolor2';
 | 
			
		||||
import { map, share } from 'rxjs/operators';
 | 
			
		||||
import { MarkerShapesComponent } from '@home/components/widget/lib/settings/common/map/marker-shapes.component';
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,7 @@ import {
 | 
			
		||||
  createColorMarkerShapeURI,
 | 
			
		||||
  MarkerShape, markerShapes,
 | 
			
		||||
  tripMarkerShapes
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/marker-shape.models';
 | 
			
		||||
} from '@shared/models/widget/maps/marker-shape.models';
 | 
			
		||||
import { Observable } from 'rxjs';
 | 
			
		||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
 | 
			
		||||
import { MatIconRegistry } from '@angular/material/icon';
 | 
			
		||||
 | 
			
		||||
@ -29,16 +29,8 @@ import { merge } from 'rxjs';
 | 
			
		||||
import { WidgetService } from '@core/http/widget.service';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import {
 | 
			
		||||
  DataLayerPatternSettings,
 | 
			
		||||
  DataLayerPatternType,
 | 
			
		||||
  DataLayerTooltipSettings,
 | 
			
		||||
  dataLayerTooltipTriggers,
 | 
			
		||||
  dataLayerTooltipTriggerTranslationMap,
 | 
			
		||||
  pathDecoratorSymbols, pathDecoratorSymbolTranslationMap,
 | 
			
		||||
  TripTimelineSettings
 | 
			
		||||
} from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import { coerceBoolean } from '@shared/decorators/coercion';
 | 
			
		||||
import { MapSettingsContext } from '@home/components/widget/lib/settings/common/map/map-settings.component.models';
 | 
			
		||||
} from '@shared/models/widget/maps/map.models';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'tb-trip-timeline-settings',
 | 
			
		||||
@ -166,7 +158,4 @@ export class TripTimelineSettingsComponent implements OnInit, ControlValueAccess
 | 
			
		||||
    this.modelValue = this.tripTimelineSettingsFormGroup.getRawValue();
 | 
			
		||||
    this.propagateChange(this.modelValue);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected readonly pathDecoratorSymbols = pathDecoratorSymbols;
 | 
			
		||||
  protected readonly pathDecoratorSymbolTranslationMap = pathDecoratorSymbolTranslationMap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -66,7 +66,7 @@
 | 
			
		||||
                          [globalVariables]="functionScopeVariables"
 | 
			
		||||
                          [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                          functionTitle="{{ 'widgets.maps.circle-label-function' | translate }}"
 | 
			
		||||
                          helpId="widget/lib/map/label_fn">
 | 
			
		||||
                          helpId="widget/lib/map-legacy/label_fn">
 | 
			
		||||
              </tb-js-func>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </mat-expansion-panel>
 | 
			
		||||
@ -110,7 +110,7 @@
 | 
			
		||||
                          [globalVariables]="functionScopeVariables"
 | 
			
		||||
                          [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                          functionTitle="{{ 'widgets.maps.circle-tooltip-function' | translate }}"
 | 
			
		||||
                          helpId="widget/lib/map/polygon_tooltip_fn">
 | 
			
		||||
                          helpId="widget/lib/map-legacy/polygon_tooltip_fn">
 | 
			
		||||
              </tb-js-func>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </mat-expansion-panel>
 | 
			
		||||
@ -146,7 +146,7 @@
 | 
			
		||||
                          [globalVariables]="functionScopeVariables"
 | 
			
		||||
                          [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                          functionTitle="{{ 'widgets.maps.circle-fill-color-function' | translate }}"
 | 
			
		||||
                          helpId="widget/lib/map/polygon_color_fn">
 | 
			
		||||
                          helpId="widget/lib/map-legacy/polygon_color_fn">
 | 
			
		||||
              </tb-js-func>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </mat-expansion-panel>
 | 
			
		||||
@ -186,7 +186,7 @@
 | 
			
		||||
                          [globalVariables]="functionScopeVariables"
 | 
			
		||||
                          [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                          functionTitle="{{ 'widgets.maps.circle-stroke-color-function' | translate }}"
 | 
			
		||||
                          helpId="widget/lib/map/polygon_color_fn">
 | 
			
		||||
                          helpId="widget/lib/map-legacy/polygon_color_fn">
 | 
			
		||||
              </tb-js-func>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </mat-expansion-panel>
 | 
			
		||||
 | 
			
		||||
@ -82,7 +82,7 @@
 | 
			
		||||
                          [globalVariables]="functionScopeVariables"
 | 
			
		||||
                          [functionArgs]="['data', 'childCount']"
 | 
			
		||||
                          functionTitle="{{ 'widgets.maps.marker-color-function' | translate }}"
 | 
			
		||||
                          helpId="widget/lib/map/clustering_color_fn">
 | 
			
		||||
                          helpId="widget/lib/map-legacy/clustering_color_fn">
 | 
			
		||||
              </tb-js-func>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </mat-expansion-panel>
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@
 | 
			
		||||
                [globalVariables]="functionScopeVariables"
 | 
			
		||||
                [functionArgs]="['origXPos', 'origYPos', 'data', 'dsData', 'dsIndex', 'aspect']"
 | 
			
		||||
                functionTitle="{{ 'widgets.maps.position-function' | translate }}"
 | 
			
		||||
                helpId="widget/lib/map/position_fn">
 | 
			
		||||
                helpId="widget/lib/map-legacy/position_fn">
 | 
			
		||||
    </tb-js-func>
 | 
			
		||||
    <mat-checkbox formControlName="draggableMarker">
 | 
			
		||||
      {{ 'widgets.maps.draggable-marker' | translate }}
 | 
			
		||||
@ -68,7 +68,7 @@
 | 
			
		||||
                      [globalVariables]="functionScopeVariables"
 | 
			
		||||
                      [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                      functionTitle="{{ 'widgets.maps.label-function' | translate }}"
 | 
			
		||||
                      helpId="widget/lib/map/label_fn">
 | 
			
		||||
                      helpId="widget/lib/map-legacy/label_fn">
 | 
			
		||||
          </tb-js-func>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
      </mat-expansion-panel>
 | 
			
		||||
@ -112,7 +112,7 @@
 | 
			
		||||
                      [globalVariables]="functionScopeVariables"
 | 
			
		||||
                      [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                      functionTitle="{{ 'widgets.maps.tooltip-function' | translate }}"
 | 
			
		||||
                      helpId="widget/lib/map/tooltip_fn">
 | 
			
		||||
                      helpId="widget/lib/map-legacy/tooltip_fn">
 | 
			
		||||
          </tb-js-func>
 | 
			
		||||
          <section class="flex flex-row xs:flex-col gt-xs:gap-2">
 | 
			
		||||
            <mat-form-field class="flex-1">
 | 
			
		||||
@ -151,7 +151,7 @@
 | 
			
		||||
                      [globalVariables]="functionScopeVariables"
 | 
			
		||||
                      [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                      functionTitle="{{ 'widgets.maps.color-function' | translate }}"
 | 
			
		||||
                      helpId="widget/lib/map/color_fn">
 | 
			
		||||
                      helpId="widget/lib/map-legacy/color_fn">
 | 
			
		||||
          </tb-js-func>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
      </mat-expansion-panel>
 | 
			
		||||
@ -185,7 +185,7 @@
 | 
			
		||||
                      [globalVariables]="functionScopeVariables"
 | 
			
		||||
                      [functionArgs]="['data', 'images', 'dsData', 'dsIndex']"
 | 
			
		||||
                      functionTitle="{{ 'widgets.maps.marker-image-function' | translate }}"
 | 
			
		||||
                      helpId="widget/lib/map/marker_image_fn">
 | 
			
		||||
                      helpId="widget/lib/map-legacy/marker_image_fn">
 | 
			
		||||
          </tb-js-func>
 | 
			
		||||
          <tb-multiple-gallery-image-input [class.!hidden]="!markersSettingsFormGroup.get('useMarkerImageFunction').value"
 | 
			
		||||
                                           label="{{ 'widgets.maps.marker-images' | translate }}"
 | 
			
		||||
 | 
			
		||||
@ -66,7 +66,7 @@
 | 
			
		||||
                          [globalVariables]="functionScopeVariables"
 | 
			
		||||
                          [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                          functionTitle="{{ 'widgets.maps.polygon-label-function' | translate }}"
 | 
			
		||||
                          helpId="widget/lib/map/label_fn">
 | 
			
		||||
                          helpId="widget/lib/map-legacy/label_fn">
 | 
			
		||||
              </tb-js-func>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </mat-expansion-panel>
 | 
			
		||||
@ -110,7 +110,7 @@
 | 
			
		||||
                          [globalVariables]="functionScopeVariables"
 | 
			
		||||
                          [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                          functionTitle="{{ 'widgets.maps.polygon-tooltip-function' | translate }}"
 | 
			
		||||
                          helpId="widget/lib/map/polygon_tooltip_fn">
 | 
			
		||||
                          helpId="widget/lib/map-legacy/polygon_tooltip_fn">
 | 
			
		||||
              </tb-js-func>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </mat-expansion-panel>
 | 
			
		||||
@ -146,7 +146,7 @@
 | 
			
		||||
                          [globalVariables]="functionScopeVariables"
 | 
			
		||||
                          [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                          functionTitle="{{ 'widgets.maps.polygon-color-function' | translate }}"
 | 
			
		||||
                          helpId="widget/lib/map/polygon_color_fn">
 | 
			
		||||
                          helpId="widget/lib/map-legacy/polygon_color_fn">
 | 
			
		||||
              </tb-js-func>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </mat-expansion-panel>
 | 
			
		||||
@ -186,7 +186,7 @@
 | 
			
		||||
                          [globalVariables]="functionScopeVariables"
 | 
			
		||||
                          [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                          functionTitle="{{ 'widgets.maps.polygon-stroke-color-function' | translate }}"
 | 
			
		||||
                          helpId="widget/lib/map/polygon_color_fn">
 | 
			
		||||
                          helpId="widget/lib/map-legacy/polygon_color_fn">
 | 
			
		||||
              </tb-js-func>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </mat-expansion-panel>
 | 
			
		||||
 | 
			
		||||
@ -85,7 +85,7 @@
 | 
			
		||||
                      [globalVariables]="functionScopeVariables"
 | 
			
		||||
                      [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                      functionTitle="{{ 'widgets.maps.tooltip-function' | translate }}"
 | 
			
		||||
                      helpId="widget/lib/map/tooltip_fn">
 | 
			
		||||
                      helpId="widget/lib/map-legacy/tooltip_fn">
 | 
			
		||||
          </tb-js-func>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
      </mat-expansion-panel>
 | 
			
		||||
 | 
			
		||||
@ -50,7 +50,7 @@
 | 
			
		||||
                      [globalVariables]="functionScopeVariables"
 | 
			
		||||
                      [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                      functionTitle="{{ 'widgets.maps.label-function' | translate }}"
 | 
			
		||||
                      helpId="widget/lib/map/label_fn">
 | 
			
		||||
                      helpId="widget/lib/map-legacy/label_fn">
 | 
			
		||||
          </tb-js-func>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
      </mat-expansion-panel>
 | 
			
		||||
@ -84,7 +84,7 @@
 | 
			
		||||
                      [globalVariables]="functionScopeVariables"
 | 
			
		||||
                      [functionArgs]="['data', 'images', 'dsData', 'dsIndex']"
 | 
			
		||||
                      functionTitle="{{ 'widgets.maps.marker-image-function' | translate }}"
 | 
			
		||||
                      helpId="widget/lib/map/marker_image_fn">
 | 
			
		||||
                      helpId="widget/lib/map-legacy/marker_image_fn">
 | 
			
		||||
          </tb-js-func>
 | 
			
		||||
          <tb-multiple-gallery-image-input [class.!hidden]="!tripAnimationMarkerSettingsFormGroup.get('useMarkerImageFunction').value"
 | 
			
		||||
                                           label="{{ 'widgets.maps.marker-images' | translate }}"
 | 
			
		||||
 | 
			
		||||
@ -51,7 +51,7 @@
 | 
			
		||||
                    [globalVariables]="functionScopeVariables"
 | 
			
		||||
                    [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                    functionTitle="{{ 'widgets.maps.path-color-function' | translate }}"
 | 
			
		||||
                    helpId="widget/lib/map/path_color_fn">
 | 
			
		||||
                    helpId="widget/lib/map-legacy/path_color_fn">
 | 
			
		||||
        </tb-js-func>
 | 
			
		||||
      </ng-template>
 | 
			
		||||
    </mat-expansion-panel>
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,7 @@
 | 
			
		||||
                        [globalVariables]="functionScopeVariables"
 | 
			
		||||
                        [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                        functionTitle="{{ 'widgets.maps.point-color-function' | translate }}"
 | 
			
		||||
                        helpId="widget/lib/map/path_point_color_fn">
 | 
			
		||||
                        helpId="widget/lib/map-legacy/path_point_color_fn">
 | 
			
		||||
            </tb-js-func>
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        </mat-expansion-panel>
 | 
			
		||||
@ -80,7 +80,7 @@
 | 
			
		||||
                        [globalVariables]="functionScopeVariables"
 | 
			
		||||
                        [functionArgs]="['data', 'dsData', 'dsIndex']"
 | 
			
		||||
                        functionTitle="{{ 'widgets.maps.point-as-anchor-function' | translate }}"
 | 
			
		||||
                        helpId="widget/lib/map/trip_point_as_anchor_fn">
 | 
			
		||||
                        helpId="widget/lib/map-legacy/trip_point_as_anchor_fn">
 | 
			
		||||
            </tb-js-func>
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        </mat-expansion-panel>
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.m
 | 
			
		||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
 | 
			
		||||
import { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@core/core.state';
 | 
			
		||||
import { isDefinedAndNotNull, mergeDeep, mergeDeepIgnoreArray } from '@core/utils';
 | 
			
		||||
import { isDefinedAndNotNull, mergeDeepIgnoreArray } from '@core/utils';
 | 
			
		||||
import { mapWidgetDefaultSettings, MapWidgetSettings } from '@home/components/widget/lib/maps/map-widget.models';
 | 
			
		||||
import { WidgetConfigComponentData } from '@home/models/widget-component.models';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -307,23 +307,23 @@ export class ImportExportService {
 | 
			
		||||
                            }
 | 
			
		||||
                          }
 | 
			
		||||
                          return this.addImportedWidget(dashboard, targetState, targetLayoutFunction, widget,
 | 
			
		||||
                            aliasesInfo, filtersInfo, onAliasesUpdateFunction, onFiltersUpdateFunction, originalColumns, originalSize);
 | 
			
		||||
                            aliasesInfo, filtersInfo, onAliasesUpdateFunction, onFiltersUpdateFunction, originalColumns, originalSize, widgetItem.widgetExportInfo);
 | 
			
		||||
                        }
 | 
			
		||||
                      ));
 | 
			
		||||
                    } else {
 | 
			
		||||
                      return this.addImportedWidget(dashboard, targetState, targetLayoutFunction, widget,
 | 
			
		||||
                        aliasesInfo, filtersInfo, onAliasesUpdateFunction, onFiltersUpdateFunction, originalColumns, originalSize);
 | 
			
		||||
                        aliasesInfo, filtersInfo, onAliasesUpdateFunction, onFiltersUpdateFunction, originalColumns, originalSize, widgetItem.widgetExportInfo);
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                )
 | 
			
		||||
              );
 | 
			
		||||
            } else {
 | 
			
		||||
              return this.addImportedWidget(dashboard, targetState, targetLayoutFunction, widget,
 | 
			
		||||
                aliasesInfo, filtersInfo, onAliasesUpdateFunction, onFiltersUpdateFunction, originalColumns, originalSize);
 | 
			
		||||
                aliasesInfo, filtersInfo, onAliasesUpdateFunction, onFiltersUpdateFunction, originalColumns, originalSize, widgetItem.widgetExportInfo);
 | 
			
		||||
            }
 | 
			
		||||
          } else {
 | 
			
		||||
            return this.addImportedWidget(dashboard, targetState, targetLayoutFunction, widget,
 | 
			
		||||
              aliasesInfo, filtersInfo, onAliasesUpdateFunction, onFiltersUpdateFunction, originalColumns, originalSize);
 | 
			
		||||
              aliasesInfo, filtersInfo, onAliasesUpdateFunction, onFiltersUpdateFunction, originalColumns, originalSize, widgetItem.widgetExportInfo);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }),
 | 
			
		||||
@ -1033,11 +1033,11 @@ export class ImportExportService {
 | 
			
		||||
                            filtersInfo: FiltersInfo,
 | 
			
		||||
                            onAliasesUpdateFunction: () => void,
 | 
			
		||||
                            onFiltersUpdateFunction: () => void,
 | 
			
		||||
                            originalColumns: number, originalSize: WidgetSize): Observable<ImportWidgetResult> {
 | 
			
		||||
                            originalColumns: number, originalSize: WidgetSize, widgetExportInfo: any): Observable<ImportWidgetResult> {
 | 
			
		||||
    return targetLayoutFunction().pipe(
 | 
			
		||||
      mergeMap((targetLayout) => this.itembuffer.addWidgetToDashboard(dashboard, targetState, targetLayout,
 | 
			
		||||
          widget, aliasesInfo, filtersInfo, onAliasesUpdateFunction, onFiltersUpdateFunction,
 | 
			
		||||
          originalColumns, originalSize, -1, -1).pipe(
 | 
			
		||||
          originalColumns, originalSize, -1, -1, 'default', widgetExportInfo).pipe(
 | 
			
		||||
          map(() => ({widget, layoutId: targetLayout} as ImportWidgetResult))
 | 
			
		||||
        )
 | 
			
		||||
    ));
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@ import { EntityType } from '@shared/models/entity-type.models';
 | 
			
		||||
import { EntityId } from '@shared/models/id/entity-id';
 | 
			
		||||
import { EntitySearchDirection, RelationEntityTypeFilter } from '@shared/models/relation.models';
 | 
			
		||||
import { EntityFilter } from '@shared/models/query/query.models';
 | 
			
		||||
import { guid, isEqual } from '@core/utils';
 | 
			
		||||
 | 
			
		||||
export enum AliasFilterType {
 | 
			
		||||
  singleEntity = 'singleEntity',
 | 
			
		||||
@ -210,3 +211,41 @@ export interface EntityAliasFilterResult {
 | 
			
		||||
  entityFilter: EntityFilter;
 | 
			
		||||
  entityParamName?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const getEntityAliasId = (entityAliases: EntityAliases, aliasInfo: EntityAliasInfo): string => {
 | 
			
		||||
  let newAliasId: string;
 | 
			
		||||
  for (const aliasId of Object.keys(entityAliases)) {
 | 
			
		||||
    if (isEntityAliasEqual(entityAliases[aliasId], aliasInfo)) {
 | 
			
		||||
      newAliasId = aliasId;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (!newAliasId) {
 | 
			
		||||
    const newAliasName = createEntityAliasName(entityAliases, aliasInfo.alias);
 | 
			
		||||
    newAliasId = guid();
 | 
			
		||||
    entityAliases[newAliasId] = {id: newAliasId, alias: newAliasName, filter: aliasInfo.filter};
 | 
			
		||||
  }
 | 
			
		||||
  return newAliasId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const isEntityAliasEqual = (alias1: EntityAliasInfo, alias2: EntityAliasInfo): boolean => {
 | 
			
		||||
  return isEqual(alias1.filter, alias2.filter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const createEntityAliasName = (entityAliases: EntityAliases, alias: string): string => {
 | 
			
		||||
  let c = 0;
 | 
			
		||||
  let newAlias = alias;
 | 
			
		||||
  let unique = false;
 | 
			
		||||
  while (!unique) {
 | 
			
		||||
    unique = true;
 | 
			
		||||
    for (const entAliasId of Object.keys(entityAliases)) {
 | 
			
		||||
      const entAlias = entityAliases[entAliasId];
 | 
			
		||||
      if (newAlias === entAlias.alias) {
 | 
			
		||||
        c++;
 | 
			
		||||
        newAlias = alias + c;
 | 
			
		||||
        unique = false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return newAlias;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,7 @@ import { EntityType } from '@shared/models/entity-type.models';
 | 
			
		||||
import { DataKey, Datasource, DatasourceType } from '@shared/models/widget.models';
 | 
			
		||||
import { PageData } from '@shared/models/page/page-data';
 | 
			
		||||
import {
 | 
			
		||||
  guid,
 | 
			
		||||
  isArraysEqualIgnoreUndefined,
 | 
			
		||||
  isDefined,
 | 
			
		||||
  isDefinedAndNotNull,
 | 
			
		||||
@ -921,3 +922,42 @@ export function updateDatasourceFromEntityInfo(datasource: Datasource, entity: E
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const getFilterId = (filters: Filters, filterInfo: FilterInfo): string => {
 | 
			
		||||
  let newFilterId: string;
 | 
			
		||||
  for (const filterId of Object.keys(filters)) {
 | 
			
		||||
    if (isFilterEqual(filters[filterId], filterInfo)) {
 | 
			
		||||
      newFilterId = filterId;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (!newFilterId) {
 | 
			
		||||
    const newFilterName = createFilterName(filters, filterInfo.filter);
 | 
			
		||||
    newFilterId = guid();
 | 
			
		||||
    filters[newFilterId] = {id: newFilterId, filter: newFilterName,
 | 
			
		||||
      keyFilters: filterInfo.keyFilters, editable: filterInfo.editable};
 | 
			
		||||
  }
 | 
			
		||||
  return newFilterId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const isFilterEqual = (filter1: FilterInfo, filter2: FilterInfo): boolean => {
 | 
			
		||||
  return isEqual(filter1.keyFilters, filter2.keyFilters);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const createFilterName = (filters: Filters, filter: string): string => {
 | 
			
		||||
  let c = 0;
 | 
			
		||||
  let newFilter = filter;
 | 
			
		||||
  let unique = false;
 | 
			
		||||
  while (!unique) {
 | 
			
		||||
    unique = true;
 | 
			
		||||
    for (const entFilterId of Object.keys(filters)) {
 | 
			
		||||
      const entFilter = filters[entFilterId];
 | 
			
		||||
      if (newFilter === entFilter.filter) {
 | 
			
		||||
        c++;
 | 
			
		||||
        newFilter = filter + c;
 | 
			
		||||
        unique = false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return newFilter;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										151
									
								
								ui-ngx/src/app/shared/models/widget/maps/map-export.models.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								ui-ngx/src/app/shared/models/widget/maps/map-export.models.ts
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -39,7 +39,7 @@ import { TbFunction } from '@shared/models/js-function.models';
 | 
			
		||||
import { Observable, Observer, of, switchMap } from 'rxjs';
 | 
			
		||||
import { map } from 'rxjs/operators';
 | 
			
		||||
import { ImagePipe } from '@shared/pipe/image.pipe';
 | 
			
		||||
import { MarkerShape } from '@home/components/widget/lib/maps/models/marker-shape.models';
 | 
			
		||||
import { MarkerShape } from '@shared/models/widget/maps/marker-shape.models';
 | 
			
		||||
import { DateFormatSettings, simpleDateFormat } from '@shared/models/widget-settings.models';
 | 
			
		||||
 | 
			
		||||
export enum MapType {
 | 
			
		||||
@ -205,7 +205,7 @@ export const createColorMarkerIconElement = (iconRegistry: MatIconRegistry, domS
 | 
			
		||||
 | 
			
		||||
let placeItemIconURI$: Observable<string>;
 | 
			
		||||
 | 
			
		||||
export const createPlaceItemIcon= (iconRegistry: MatIconRegistry, domSanitizer: DomSanitizer): Observable<string> => {
 | 
			
		||||
export const createPlaceItemIcon = (iconRegistry: MatIconRegistry, domSanitizer: DomSanitizer): Observable<string> => {
 | 
			
		||||
  if (placeItemIconURI$) {
 | 
			
		||||
    return placeItemIconURI$;
 | 
			
		||||
  }
 | 
			
		||||
							
								
								
									
										35
									
								
								ui-ngx/src/app/shared/models/widget/widget-export.models.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ui-ngx/src/app/shared/models/widget/widget-export.models.ts
									
									
									
									
									
										Normal file
									
								
							@ -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>
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ A JavaScript function used to compute color of the polygon.
 | 
			
		||||
**Parameters:**
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
  {% include widget/lib/map/map_fn_args %}
 | 
			
		||||
  {% include widget/lib/map-legacy/map_fn_args %}
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
**Returns:**
 | 
			
		||||
@ -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 %}
 | 
			
		||||
@ -10,9 +10,9 @@ 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>
 | 
			
		||||
  <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>
 | 
			
		||||
    - 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.
 | 
			
		||||
     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>childCount:</b> <code>number</code> - the total number of markers contained within that cluster
 | 
			
		||||
  </li>
 | 
			
		||||
@ -22,7 +22,7 @@ A JavaScript function used to compute clustering marker color.
 | 
			
		||||
 | 
			
		||||
Should return string value presenting color of the marker.
 | 
			
		||||
 | 
			
		||||
In case no data is returned, color value from **Color** settings field will be used.
 | 
			
		||||
In case no data is returned, default colors will be used depending on number of markers within that cluster.
 | 
			
		||||
 | 
			
		||||
<div class="divider"></div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
<div class="divider"></div>
 | 
			
		||||
<br/>
 | 
			
		||||
 | 
			
		||||
*function (data, dsData, dsIndex): string*
 | 
			
		||||
*function (data, dsData): string*
 | 
			
		||||
 | 
			
		||||
A JavaScript function used to compute color of the marker.
 | 
			
		||||
 | 
			
		||||
@ -21,22 +21,4 @@ In case no data is returned, color value from **Color** settings field will be u
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
{% include widget/lib/map/color_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>
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
<div class="divider"></div>
 | 
			
		||||
<br/>
 | 
			
		||||
 | 
			
		||||
*function (data, dsData, dsIndex): string*
 | 
			
		||||
*function (data, dsData): string*
 | 
			
		||||
 | 
			
		||||
A JavaScript function used to compute text or HTML code of the marker label.
 | 
			
		||||
 | 
			
		||||
@ -19,22 +19,4 @@ 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>
 | 
			
		||||
{% include widget/lib/map/label_fn_examples %}
 | 
			
		||||
 | 
			
		||||
@ -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>
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
@ -3,14 +3,14 @@
 | 
			
		||||
<div class="divider"></div>
 | 
			
		||||
<br/>
 | 
			
		||||
 | 
			
		||||
*function (data, images, dsData, dsIndex): {url: string, size: number}*
 | 
			
		||||
*function (data, images, dsData): {url: string, size: number}*
 | 
			
		||||
 | 
			
		||||
A JavaScript function used to compute marker image.
 | 
			
		||||
 | 
			
		||||
**Parameters:**
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
  {% include widget/lib/map/map_fn_args %}
 | 
			
		||||
  {% include widget/lib/map/marker_image_fn_args %}
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
**Returns:**
 | 
			
		||||
@ -19,13 +19,17 @@ Should return marker image data having the following structure:
 | 
			
		||||
 | 
			
		||||
```typescript
 | 
			
		||||
{
 | 
			
		||||
   url: string,
 | 
			
		||||
   size: number
 | 
			
		||||
  url: string;
 | 
			
		||||
  size: number;
 | 
			
		||||
  markerOffset?: [number, number];
 | 
			
		||||
  tooltipOffset?: [number, number];
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- *url* - marker image url;
 | 
			
		||||
- *size* - marker image size;
 | 
			
		||||
- *markerOffset* - optional array of two numbers presenting relative horizontal and vertical offset of the marker image;
 | 
			
		||||
- *tooltipOffset* - optional array of two numbers presenting relative horizontal and vertical offset of the marker image tooltip;
 | 
			
		||||
 | 
			
		||||
In case no data is returned, default marker image will be used. 
 | 
			
		||||
 | 
			
		||||
@ -41,13 +45,13 @@ Let's assume 4 images are defined in <b>Marker images</b> section. Each image co
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
var type = data['Type'];
 | 
			
		||||
var type = data.Type;
 | 
			
		||||
if (type == 'thermometer') {
 | 
			
		||||
  var res = {
 | 
			
		||||
    url: images[0],
 | 
			
		||||
    size: 40
 | 
			
		||||
  }
 | 
			
		||||
  var temperature = data['temperature'];
 | 
			
		||||
  var temperature = data.temperature;
 | 
			
		||||
  if (typeof temperature !== undefined) {
 | 
			
		||||
    var percent = (temperature + 60)/120;
 | 
			
		||||
    var index = Math.min(3, Math.floor(4 * percent));
 | 
			
		||||
 | 
			
		||||
@ -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>
 | 
			
		||||
  
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
<div class="divider"></div>
 | 
			
		||||
<br/>
 | 
			
		||||
 | 
			
		||||
*function (data, dsData, dsIndex): string*
 | 
			
		||||
*function (data, dsData): string*
 | 
			
		||||
 | 
			
		||||
A JavaScript function used to compute color of the trip path.
 | 
			
		||||
 | 
			
		||||
@ -17,26 +17,8 @@ A JavaScript function used to compute color of the trip path.
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
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>
 | 
			
		||||
{% include widget/lib/map/color_fn_examples %}
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
<div class="divider"></div>
 | 
			
		||||
<br/>
 | 
			
		||||
 | 
			
		||||
*function (data, dsData, dsIndex): string*
 | 
			
		||||
*function (data, dsData): string*
 | 
			
		||||
 | 
			
		||||
A JavaScript function used to compute color of the trip path point.
 | 
			
		||||
 | 
			
		||||
@ -17,27 +17,8 @@ A JavaScript function used to compute color of the trip path point.
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
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>
 | 
			
		||||
 | 
			
		||||
{% include widget/lib/map/color_fn_examples %}
 | 
			
		||||
 | 
			
		||||
@ -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 %}
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
<div class="divider"></div>
 | 
			
		||||
<br/>
 | 
			
		||||
 | 
			
		||||
*function (data, dsData, dsIndex): string*
 | 
			
		||||
*function (data, dsData): string*
 | 
			
		||||
 | 
			
		||||
A JavaScript function used to compute text or HTML code to be displayed in the polygon tooltip.
 | 
			
		||||
 | 
			
		||||
@ -15,26 +15,8 @@ A JavaScript function used to compute text or HTML code to be displayed in the p
 | 
			
		||||
 | 
			
		||||
**Returns:**
 | 
			
		||||
 | 
			
		||||
Should return string value presenting text or HTML for the polygon tooltip.
 | 
			
		||||
Should return string value presenting text or HTML for the 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>
 | 
			
		||||
{% include widget/lib/map/tooltip_fn_examples %}
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
<div class="divider"></div>
 | 
			
		||||
<br/>
 | 
			
		||||
 | 
			
		||||
*function (origXPos, origYPos, data, dsData, dsIndex, aspect): {x: number, y: number}*
 | 
			
		||||
*function (origXPos, origYPos, data, dsData, aspect): {x: number, y: number}*
 | 
			
		||||
 | 
			
		||||
A JavaScript function used to convert original relative x, y coordinates of the marker.
 | 
			
		||||
 | 
			
		||||
@ -22,8 +22,8 @@ Should return position data having the following structure:
 | 
			
		||||
 | 
			
		||||
```typescript
 | 
			
		||||
{ 
 | 
			
		||||
   x: number,
 | 
			
		||||
   y: number
 | 
			
		||||
   x: number;
 | 
			
		||||
   y: number;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,9 +3,9 @@
 | 
			
		||||
<div class="divider"></div>
 | 
			
		||||
<br/>
 | 
			
		||||
 | 
			
		||||
*function (data, dsData, dsIndex): string*
 | 
			
		||||
*function (data, dsData): string*
 | 
			
		||||
 | 
			
		||||
A JavaScript function used to compute text or HTML code to be displayed in the marker, point or polygon tooltip.
 | 
			
		||||
A JavaScript function used to compute text or HTML code to be displayed in the marker tooltip.
 | 
			
		||||
 | 
			
		||||
**Parameters:**
 | 
			
		||||
 | 
			
		||||
@ -19,22 +19,4 @@ 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>
 | 
			
		||||
{% include widget/lib/map/tooltip_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>
 | 
			
		||||
@ -1,9 +1,9 @@
 | 
			
		||||
#### Point as anchor function
 | 
			
		||||
#### Location snap filter function
 | 
			
		||||
 | 
			
		||||
<div class="divider"></div>
 | 
			
		||||
<br/>
 | 
			
		||||
 | 
			
		||||
*function (data, dsData, dsIndex): boolean*
 | 
			
		||||
*function (data, dsData): boolean*
 | 
			
		||||
 | 
			
		||||
A JavaScript function evaluating whether to use trip point as time anchor used in time selector.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								ui-ngx/src/typings/leaflet-extend-tb.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								ui-ngx/src/typings/leaflet-extend-tb.d.ts
									
									
									
									
										vendored
									
									
								
							@ -15,8 +15,8 @@
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
import { FormattedData } from '@shared/models/widget.models';
 | 
			
		||||
import L, { Control, ControlOptions } from 'leaflet';
 | 
			
		||||
import { TbMapDatasource } from '@home/components/widget/lib/maps/models/map.models';
 | 
			
		||||
import L from 'leaflet';
 | 
			
		||||
import { TbMapDatasource } from '@shared/models/widget/maps/map.models';
 | 
			
		||||
import { MatIconRegistry } from '@angular/material/icon';
 | 
			
		||||
 | 
			
		||||
// redeclare module, maintains compatibility with @types/leaflet
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user