Skip to main content
Version: 4.0.24

3DVisualizr for ThingWorx

Last updated: March 8, 2021

Prerequisites/Dependencies

NameVersion
ThingWorx7.4.0  

Current Version

NameFilenameVersion
Elisa3DViewerCore_ExtensionPackageElisa3DViewerRelease.zip 4.0.25  
Elisa3DViewerModel_ExtensionPackageElisa3DViewerModel.zip 1.0.13  

Introduction and Installation

The 3d viewer is designed to view and visualise factory data in a 3d format by connecting data sources to virtual assets. Virtual assets can display their state, by changing their colour based on some predefined rules, and kpis in a label that can be attached to each individual asset.

Step Screenshot(s)
After logging into the Composer as Administrator, click on the Import/Export button and click on the Import option at the top. From the opened popup, select Extension as the Import Option from the dropdown menu.Imgur1 Imgur1a
Click Browse and select the extension Elisa3DViewerRelease.zip. You can click Validate to make sure everything's right with the extension and that Thingworx can actually import it. Imgur2
After validating the extension, click on the green Import button and wait for the extension to install. The installation might take a while as the extension ships with an example BABYLON file located at .../Elisa3DViewerCore_ExtensionPackage/ui/Elisa3DViewer/models/PTC_Robot.babylonImgur3

At this point, if you want, you can also install the extension called Elisa3DViewerModel_ExtensionPackage that ships in the same download. The model extension contains useful DataShapes, ThingShapes and an example Thing and a Mashup showcasing how to use the viewer to get you up to speed quickly. Using/installing this extension is completely optional and the 3d viewer core can be used without having the model extension installed.

info

We'll be using the Mashup provided in the model extension as an example within this documentation

Step Screenshot(s)
To install the model extension, follow the procedures above but when browsing for the extension to install, select the Elisa3DViewerModel.zip insteadImgur4
You can verify that everything installed as expected by taking a look at the contents of each package. 
Contents of Elisa3DViewerCore_ExtensionPackageImgur5
Contents of Elisa3DViewerModel_ExtensionPackageImgur6

Properties

Property definitions

The following is a list of ALL properties within the 3d viewer showing their Description, Base types and Default values. Table(s) of additional property attributes can be found later in the document.

Name DescriptionBase typeDefault value
BoneDataBone data array as infotableINFOTABLE0
BoneDataModelIdFieldDESCRIPTION MISSINGFIELDNAMEobjectId
BoneRotationsFieldBone rotations used to animate/rotate bones in a skeleton meshFIELDNAMEboneRotations
AnimationStateMesh animation state as infotableINFOTABLE0
AnimationStateModelIdFieldField name to get the mesh id fromFIELDNAMEmeshId
AnimationStateTargetFrameFieldField name to get the target (frame) fromFIELDNAMEanimationTarget
AnimationStatePlayFieldField name to get the whether to play the animation or jump to target fromFIELDNAMEanimationPlay
AnimationStateLoopFieldField name to get whether to loop the animation fromFIELDNAMEanimationLoop
AnimationStateDirectionFieldField name to get animation direction fromFIELDNAMEanimationDirection
AnnotationDataAnnotation data array as infotableINFOTABLE0
AnnotationColorFieldField name that defines the color of the annotationFIELDNAME
AnnotationIconFieldField name that defines the icon of the annotationFIELDNAME
AnnotationIdFieldField name that defines the id of the annotationFIELDNAME
AnnotationMeshIdFieldField name that defines the mesh id that the annotation will create and bind toFIELDNAME
AnnotationPositionFieldField name that defines the position of the annotationFIELDNAME
CameraFollowObjectsIf set to true, camera will follow moving objects (dynamic objects)BOOLEAN
CameraFollowRotationIf set to true, camera will act as if it was parented to the moving object. This value depends on CameraFollowObjectsBOOLEAN
CameraDefaultPositionDefault camera position, gets updated when UpdateCameraDefaultTransform is calledVEC3500,500,500
CameraDefaultTargetPositionDefault camera target position, gets updated when UpdateCameraDefaultTransform is calledVEC30,0,0
CameraRelativePositionCurrent camera position relative to target position, gets updated when CameraTransformUpdated is calledVEC3500,500,500
CameraRelativeTargetPositionCurrent camera orbit/lookat position, gets updated when CameraTransformUpdated is calledVEC30,0,0
CameraPathCamera path animation in .JSON format, gets updated when CameraPathUpdated is calledSTRING[]
CameraPathSpeedCamera path animation speed in units per secondNUMBER200
CameraPanningSensitivityCamera panning sensitivity, bigger value will make the camera pan fasterNUMBER0.5
CameraAngularSensitivityCamera angular sensitivity, smaller value will make the camera turn fasterNUMBER500
CameraMinimumRadiusMinimum radius/distance from the focus point. Used for arc ball rotate camera (default camera). Set to <0 for no limitNUMBER1
CameraMaximumRadiusMaximum radius/distance from the focus point. Used for arc ball rotate camera (default camera). Set to <0 for no limitNUMBER-1
Camera2DWhether to use a "2d"/panning only camera (rotations disabled)BOOLEAN
Camera2DAutoDistanceScale2d camera auto transition to scene overview distance scaleNUMBER1.25
Camera2DMinDistanceToZeroLevel2d camera minimum distance to "0-level"NUMBER100
WidthWidget widthINTEGER640
HeightWidget heightINTEGER480
CanvasRenderingWidthMaximum rendering canvas width. Needs LimitCanvasSize to be set to true. NOTE: The canvas will still be stretched to fit the space, reducing this will only affect the internal render size which can improve performance for the cost of quality.INTEGER1920
CanvasRenderingHeightMaximum rendering canvas height. Needs LimitCanvasSize to be set to true. NOTE: The canvas will still be stretched to fit the space, reducing this will only affect the internal render size which can improve performance for the cost of quality.INTEGER1080
LimitCanvasSizeWhen true, the rendering canvas width and height will be limited according to configuration.BOOLEAN
MaxFPSMaximum rendered frames per secondINTEGER144
ShowPerformanceTimingsShow rendering related timingsBOOLEAN
ShowInspectorShow scene inspectorBOOLEAN
ConstantlyUpdateViewerForce update viewer even if nothing's happening. NOTE: Use with careBOOLEAN
DebugModeEnable debug features and extra loggingBOOLEAN
EnableOfflineSupportEnable offline support, e.g. 3d model caching using client browser cache (.manifest files)BOOLEAN
EnableBackgroundGradientEnable background gradientBOOLEAN
UseOctreeShould octree be enabled for a sceneBOOLEAN
OctreeCapacityOctree leaf capacity (meshes)INTEGER8
OctreeDepthOctree maximum depth (sub-levels)INTEGER4
DebugVisualiseOctreeDebug visualise the generated octreeBOOLEAN
AutoMergeMeshesWithSimilarNameEXPERIMENTAL. Use with caution. Automatically merge meshes with similar name (xxx_y) only diffentiated by an index (e.g. table_1 and table_2)BOOLEAN
ParticleTrailStyleThe style of the particle trail. Opacity is supportedSTYLEDEFINITIONElisa3DViewer.Style.ParticleTrail
ParticleTrailSizeSize of particlesINTEGER16
ShowOnlySelectedGroupShows only the selected groupBOOLEAN
IsPickableDefaultValueAre objects pickable by default.BOOLEAN
AttachedLabelsDefinePickablesIf set to true, only objects with attached labels will be pickable.BOOLEAN
TriggerObjectHoveredEventsShould object hovered events be triggeredBOOLEAN
TriggerObjectClickedEventsShould object clicked events be triggeredBOOLEAN
DynamicObjectDataDynamic object data array as infotable, each entry adds a 3D-object to the active sceneINFOTABLE0
DynamicObjectIdFieldField which will provide the unique id (name) for dynamic object, this field should match objectName-field in other infotablesFIELDNAMEDynamicObjId
DynamicObjectModelIdFieldField which will provide the unique id (name) for modelFIELDNAMEDynamicObjModelId
DynamicObjectPositionFieldField which will provide the position for dynamic objectFIELDNAMEDynamicObjPos
DynamicObjectGeoLocationFieldField which will provide the geo location for dynamic objectFIELDNAMEDynamicObjGeoLoca
DynamicObjectUnitScaleUnit scale used in dynamic object positioning, all position values are multiplied by this valueVEC31,1,1
DynamicObjectUnitOffsetUnit offset used in dynamic object positioning, this value is added to all position values after scalingVEC30,0,0
DynamicObjectIsGeoLocatedWhether position for a dynamic object is given as geo coordinatesBOOLEAN
DynamicObjectGhostEnabledEnable ghost / object trail.

NOT WORKING PROPERLY
BOOLEAN
GeoDataInfotable containing the data for geo reference markersINFOTABLEnull
GeoRefMarkersFieldField which defines the coordinate of a reference markerFIELDNAMEreferenceMarkers
GeoRefMarkerCoordinateFieldField which defines the coordinate of a reference markerSTRINGcoordinate
GeoRefMarkerScenePosFieldField which defines the scene position of a reference markerSTRINGscenePosition
GeoFencesFieldField which defines the coordinate of a reference markerFIELDNAMEfences
GeoFenceNameFieldField which defines the name of a geo fenceSTRINGname
GeoFenceColourFieldField which defines the colour of a geo fenceSTRINGcolour
GeoFenceCoordinatesFieldField which defines an infotable containing coordinates of a geo fence (of LOCATION baseType)STRINGcoordinates
SceneUnitScaleHow scene units correspond to real-world unitsNUMBER2
SortByKPITypeSort KPIs in a label by their typeBOOLEAN
KpiDataKPI data infotable. NOTE: This is only used to determine the id's of the fields below. The actual data input is not used directly but loaded within the label data instead.INFOTABLE0
KpiIdFieldKPI id fieldFIELDNAMEid
KpiTitleFieldKPI title fieldFIELDNAMEtitle
KpiValueFieldKPI value field, NOTE: the string will be interpreted as a number if neededFIELDNAMEvalue
KpiTypeFieldKPI type field.
Current types:
0: CUSTOM_INFO - No value field specified, just title shown
1: DEFAULT - Default field with title and value
2: PROGRESS - Progress bar, requires the following additional data: min, max
3: SPEEDOMETER - Speedometer, requires the following additional data: min, max, limit
4: SPEEDBAR - Speedbar, requires the following additional data: min, max, limit
FIELDNAMEtype
KpiMinFieldKPI minimum value field (not used for all types)FIELDNAMEmin
KpiMaxFieldKPI maximum value field (not used for all types)FIELDNAMEmax
KpiLimitFieldKPI value limit field, also works as the upper limit for fields with lower limit (not used for all types)FIELDNAMElimit
KpiLowerLimitFieldKPI value lower limit field (not used for all types)FIELDNAMElowerLimit
KpiInvertedFieldWhether the "data" is inverted or not. Currently only affecting speedometer; if set to true anything below the limit will be considered to be in a bad range.FIELDNAMEinverted
KpiFontColourFieldWhich style definition field to use for colouring the kpi text/valueSTRING
KpiStyleStateFormattingOptional rules for dynamic formatting of KPIs, first state is the least importantSTATEFORMATTINGundefined
LabelDataLabel data array as infotableINFOTABLE0
LabelIdFieldField which will provide the id for the label. this has to be unique.FIELDNAMEid
LabelTitleFieldField which will provide the displayed label title, supports linebreaks with "\n" and "<br>"FIELDNAMEtitle
LabelCollapsedTitleFieldField which will provide the displayed label title when in collapsed (title only) mode, supports linebreaks with "\n" and "<br>"FIELDNAMEcollapsedTitle
LabelTextFieldField which will provide the displayed label text, supports linebreaks with "\n" and "<br>"FIELDNAMEtext
LabelKPIFieldField which will provide the displayed label kpi infotableFIELDNAMEkpiData
LabelAnimationFieldField which will provide the animation state:
- 0: Stopped
- 1: Play
FIELDNAMEanimationMode
LabelTargetObjectFieldField which will provide the name of the 3d-object that the label gets attached toFIELDNAMEobjectId
LabelLayoutModeFieldField that determines if the labels default layout mode:
- 0: Hidden
- 1: Icon only
- 2: Icon and title
- 3: Everything
- 4: Everything, not grouped
FIELDNAMElayoutMode
LabelGroupFieldField that determines the group that this label belongs to. Field affects clusteringFIELDNAMEgroup
LabelStyleIconSizeGlobal label icon size (px) used in label stylingINTEGER25
LabelStyleStateFormattingOptional rules for dynamic formatting of labels and markers, first state is the least importantSTATEFORMATTINGundefined
LabelStyleHoverThe style of the UI elements when hovered. Opacity is supportedSTYLEDEFINITIONElisa3DViewer.Style.Hover
LabelStyleSelectedThe style of the UI elements when selected. Opacity is supportedSTYLEDEFINITIONElisa3DViewer.Style.Selected
SelectedLabelIdThe currently selected label id, triggers changed event. HAS TO BE UNIQUESTRING
SelectedLabelPositionPosition of a label when selected. "Default" leaves the label where it is normally, "Home menu" positions the selected label statically next to home menu.NUMBER0
StateNumberDefinesStylePriorityState formatting value can be a number. If set to true the number will be used as a priority (e.g. high number means higher priority), otherwise priority is based on the order in which the states are defined (default).BOOLEAN
ObjectButtonFieldField from label data which will provide content for the object button next to home menu. NOTE: If nothing's selected, will fallback to object name from the scene file.FIELDNAMEtitle
ObjectDataObject data array as infotableINFOTABLE0
ObjectIdFieldName of the object (mesh) in sceneFIELDNAMEobjectName
ObjectCameraPositionFieldCamera position used to in object zooming transitionsFIELDNAMErelativePosition
ObjectTargetPositionFieldCamera target position used to in object zooming transitionsFIELDNAMErelativeTargetPosition
ObjectColorIntensityObject overlay color intensity, "intensity" can be also set with color alpha valueNUMBER0.5
SceneNameUsually the name of the factory, used in various non-critical parts of the widget.STRINGUndefined Scene
SceneModelUrlURL to the modelSTRING
SceneModelFileSizeDownload size of the modelINTEGER0
SceneConfigConfig json to the scene model fileSTRING{}
SceneBackgroundStyleThe background of the widget. Opacity is supportedSTYLEDEFINITIONElisa3DViewer.Style.SceneBg
ResetSceneOnModelChangeReset the scene whenever the model changesBOOLEAN
DynamicLightingUse dynamic lighting instead of unlit sceneBOOLEAN
GlobalLightIntensityUsed only if dynamic lighting is enabledNUMBER0.75
ActiveLayerActive mesh layer (-1 means all)INTEGER-1
SceneExportInfotable to which scene mesh data will be exported to when. Input target is only used for getting the data shape and fields for export.INFOTABLE0
SceneExportMeshIdFieldField in which the mesh id will be saved toFIELDNAMEid
SceneExportMeshNameFieldField in which the mesh name will be saved toFIELDNAMEname
SceneExportMeshPositionFieldField in which the mesh position will be saved toFIELDNAMEposition
SelectedObjectIdThe id currently selected item in the scene, triggers changed eventSTRING
SelectedGroupIdThe currently selected group in the scene, triggers changed eventSTRING
ModelDataModel data array as infotableINFOTABLE0
ModelIdFieldField which will provide the model idFIELDNAMEname
ModelUrlFieldField which will provide model url / filepathFIELDNAMEurl
ModelScaleFieldField which will provide the model scaleFIELDNAMEscale
LoadingScreenStyleThe style of the loading screen. Opacity is supportedSTYLEDEFINITIONElisa3DViewer.Style.LoadingScreen
RoutesRoute data in json formatSTRING{}
WidgetCapabilitiesCapabilities for the 3DV. Recommended to use 15 (BASIC)INTEGER15
EnableAzureInsightsWhether to enable Azure Insights analyticsBOOLEAN
AzureTrackEventsSend event triggers as events to AzureBOOLEAN

Property visibilities and data binding capabilities

The following table contains the visibility and data binding capabilities of ALL properties defined by the 3d viewer.

note

Some of the binding targets may not behave as expected during runtime and will be improved in later updates

NameIs visibleIs editable Is binding targetIs binding source
BoneData
BoneDataModelIdField
BoneRotationsField
AnimationState
AnimationStateModelIdField
AnimationStateTargetFrameField
AnimationStatePlayField
AnimationStateLoopField
AnimationStateDirectionField
AnnotationData
AnnotationColorField
AnnotationIconField
AnnotationIdField
AnnotationMeshIdField
AnnotationPositionField
CameraFollowObjects
CameraFollowRotation
CameraDefaultPosition
CameraDefaultTargetPosition
CameraRelativePosition
CameraRelativeTargetPosition
CameraPath
CameraPathSpeed
CameraPanningSensitivity
CameraAngularSensitivity
CameraMinimumRadius
CameraMaximumRadius
Camera2D
Camera2DAutoDistanceScale
Camera2DMinDistanceToZeroLevel
Width
Height
CanvasRenderingWidth
CanvasRenderingHeight
LimitCanvasSize
MaxFPS
ShowPerformanceTimings
ShowInspector
ConstantlyUpdateViewer
DebugMode
EnableOfflineSupport
EnableBackgroundGradient
UseOctree
OctreeCapacity
OctreeDepth
DebugVisualiseOctree
AutoMergeMeshesWithSimilarName
ParticleTrailStyle
ParticleTrailSize
ShowOnlySelectedGroup
IsPickableDefaultValue
AttachedLabelsDefinePickables
TriggerObjectHoveredEvents
TriggerObjectClickedEvents
DynamicObjectData
DynamicObjectIdField
DynamicObjectModelIdField
DynamicObjectPositionField
DynamicObjectGeoLocationField
DynamicObjectUnitScale
DynamicObjectUnitOffset
DynamicObjectIsGeoLocated
DynamicObjectGhostEnabled
GeoData
GeoRefMarkersField
GeoRefMarkerCoordinateField
GeoRefMarkerScenePosField
GeoFencesField
GeoFenceNameField
GeoFenceColourField
GeoFenceCoordinatesField
SceneUnitScale
SortByKPIType
KpiData
KpiIdField
KpiTitleField
KpiValueField
KpiTypeField
KpiMinField
KpiMaxField
KpiLimitField
KpiLowerLimitField
KpiInvertedField
KpiFontColourField
KpiStyleStateFormatting
LabelData
LabelIdField
LabelTitleField
LabelCollapsedTitleField
LabelTextField
LabelKPIField
LabelAnimationField
LabelTargetObjectField
LabelLayoutModeField
LabelGroupField
LabelStyleIconSize
LabelStyleStateFormatting
LabelStyleHover
LabelStyleSelected
SelectedLabelId
SelectedLabelPosition
StateNumberDefinesStylePriority
ObjectButtonField
ObjectData
ObjectIdField
ObjectCameraPositionField
ObjectTargetPositionField
ObjectColorIntensity
SceneName
SceneModelUrl
SceneModelFileSize
SceneConfig
SceneBackgroundStyle
ResetSceneOnModelChange
DynamicLighting
GlobalLightIntensity
ActiveLayer
SceneExport
SceneExportMeshIdField
SceneExportMeshNameField
SceneExportMeshPositionField
SelectedObjectId
SelectedGroupId
ModelData
ModelIdField
ModelUrlField
ModelScaleField
LoadingScreenStyle
Routes
EnableAzureInsights
AzureTrackEvents

Properties with additional requirements

The following table contains the list of all properties that have some sort of a Base type restriction, Predefined options/value or somehow depend on an Base type infotable property

NameBase type restrictionsSource property nameBase type infotable propertySelect options
BoneDataModelIdFieldSTRINGBoneData
BoneRotationsFieldSTRINGBoneData
AnimationStateModelIdFieldSTRINGAnimationState
AnimationStateTargetFrameFieldSTRINGAnimationState
AnimationStatePlayFieldSTRINGAnimationState
AnimationStateLoopFieldSTRINGAnimationState
AnimationStateDirectionFieldSTRINGAnimationState
AnnotationColorFieldSTRINGAnnotationData
AnnotationIconFieldSTRINGAnnotationData
AnnotationIdFieldSTRINGAnnotationData
AnnotationMeshIdFieldSTRINGAnnotationData
AnnotationPositionFieldVEC3AnnotationData
DynamicObjectIdFieldSTRINGDynamicObjectData
DynamicObjectModelIdFieldSTRINGDynamicObjectData
DynamicObjectPositionFieldVEC3DynamicObjectData
DynamicObjectGeoLocationFieldLOCATIONDynamicObjectData
GeoRefMarkersFieldINFOTABLEGeoData
GeoRefMarkerCoordinateFieldLOCATION
GeoRefMarkerScenePosFieldVEC3
GeoFencesFieldINFOTABLEGeoData
GeoFenceNameFieldSTRING
GeoFenceColourFieldVEC4
GeoFenceCoordinatesFieldINFOTABLE
SceneUnitScale- Millimeters
- Centimeters
- Decimeters
- Meters
- Decameters
- Hehtometers
- Kilometers
KpiIdFieldSTRINGKpiData
KpiTitleFieldSTRINGKpiData
KpiValueFieldSTRINGKpiData
KpiTypeFieldINTEGERKpiData
KpiMinFieldNUMBERKpiData
KpiMaxFieldNUMBERKpiData
KpiLimitFieldNUMBERKpiData
KpiLowerLimitFieldNUMBERKpiData
KpiInvertedFieldBOOLEANKpiData
KpiFontColourField- Background color
- Foreground color
- Line color
- Secondary background color
KpiStyleStateFormattingKpiData
LabelIdFieldSTRINGLabelData
LabelTitleFieldSTRINGLabelData
LabelCollapsedTitleFieldSTRINGLabelData
LabelTextFieldSTRINGLabelData
LabelKPIFieldINFOTABLELabelData
LabelAnimationFieldINTEGERLabelData
LabelTargetObjectFieldSTRINGLabelData
LabelLayoutModeFieldINTEGERLabelData
LabelGroupFieldSTRINGLabelData
LabelStyleStateFormattingLabelData
SelectedLabelPosition- Default
- Home menu
ObjectButtonFieldSTRINGLabelData
ObjectIdFieldSTRINGObjectData
ObjectCameraPositionFieldVEC3ObjectData
ObjectTargetPositionFieldVEC3ObjectData
SceneExportMeshIdFieldSTRINGSceneExport
SceneExportMeshNameFieldSTRINGSceneExport
SceneExportMeshPositionFieldVEC3SceneExport
ModelIdFieldSTRINGModelData
ModelUrlFieldSTRINGModelData
ModelScaleFieldVEC3ModelData

Triggers

The following table contains a list of all the Service Triggers that you can execute on the viewer

Name DescriptionWarn if not bound
TransitionCameraOnSelectedObjectIf selected object has data bound in the objectData then camera gets transitioned to the values
StartPathAnimationStarts the camera flythrough using the waypoints available in the current scene. Does nothing if no waypoints are present.
TransitionCameraToDefaultTransitions camera to the default values (CameraDefaultPosition and CameraDefaultTargetPosition)
FocusCameraOnSelectedObjectTurns camera to look at the selected object pivot point
UpdatePathAnimationSerializes path animation points to .JSON and updates CameraPath property and triggers CameraPathUpdated
UpdateCameraTransformCaptures current camera transform (position and target that the camera is orbiting) and updates those values and triggers CameraTransformUpdated
UpdateCameraDefaultTransformCaptures current camera transform (position and target that the camera is orbiting) and updates those values and triggers CameraDefaultTransformUpdated
ExportSceneExport scene mesh data to the INFOTABLE bound to SceneExport
DownloadSnapshotCreates snapshot of all the widget properties and data updates and stores it to a .json file

Events

The following table contains a list of all events emitted by the viewer during its runtime

Name DescriptionWarn if not bound
CameraPathUpdatedTriggered after UpdatePathAnimation is completed
CameraTransformUpdatedTriggered after UpdateCameraTransform is completed, if an object or group was selected then CameraRelativePosition and CameraRelativeTargetPosition were updated
CameraDefaultTransformUpdatedTriggered after UpdateCameraDefaultTransform is completed
CameraTransitionStoppedTriggers whenever a transition stops (is cancelled or finishes)
CameraTransitionDoneTriggers whenever a transition finishes
CameraTransitionToMeshDoneTriggers whenever a transition to a model/object finishes
CameraTransitionToHomeDoneTriggers whenever a transition to home finishes
GeoDataUpdatedTriggered when geo editor is closed and GeoData is updated.
AnnotationDataUpdatedTriggered when the annotation data changed (e.g. users add/move/delete an annotation)
LabelClickedIMPLEMENTATION MISSING
LabelHoveredIMPLEMENTATION MISSING
ObjectClickedTriggered when user clicks on an object
ObjectHoveredTriggered when user hovers an object
SceneExportedTriggered after ExportScene is completed
ModelLoadDoneTriggered when model loading is completed
ModelLoadErrorTriggered if something goes wrong in loading the model
MeshLoadDoneTriggered when model loading is completed
MeshLoadErrorTriggered if something goes wrong in loading the model
SelectedLabelChangedTriggered when selected label changes
SelectedObjectChangedTriggered when selected object (mesh) changes
SelectedGroupChangedTriggered when selected label group changes
HomeClickedTriggered when user clicks the home icon on the menu
GroupClickedTriggered when user clicks the group label on the menu
GroupHoveredIMPLEMENTATION MISSING

Localisation table

The following table is a list of localisation token's and their default values that can be used to localise the messages/texts within the viewer.

TokenDefault Value
e3d.generic.searchSearch
e3d.generic.allAll
e3d.generic.unsortedUnsorted
e3d.generic.enableEnable
e3d.generic.disableDisable
e3d.generic.latitudeLatitude
e3d.generic.longitudeLongitude
e3d.generic.elevationElevation
e3d.generic.nameName
e3d.generic.colourColour
e3d.generic.redRed
e3d.generic.greenGreen
e3d.generic.blueBlue
e3d.generic.alphaAlpha
e3d.generic.positionPosition
e3d.generic.notAvailableN/A
e3d.generic.showShow
e3d.generic.hideHide
e3d.generic.noneNone
e3d.loading.downloadedDownloaded
e3d.loading.settingUpSetting up scene
e3d.loading.changingSceneChanging scene
e3d.loading.clearingSceneClearing scene
e3d.loading.changingSceneChanging scene
e3d.loading.loadingSceneLoading scene
e3d.loading.initialisingPropertiesInitializing viewer properties
e3d.module.assetLibrary.titleAsset Library
e3d.module.assetLibrary.activateEditModeInfoActivate Edit Mode to Add or Move Objects
e3d.module.camera.titleCamera
e3d.module.camera.addWaypointAdd Waypoint
e3d.module.camera.removeWaypointRemove Waypoint
e3d.module.camera.saveWaypointsSave Waypoints
e3d.module.camera.flythroughFlythrough
e3d.module.camera.focusPointsCamera Focus Points
e3d.module.camera.saveDefaultTransformSave Default Transform
e3d.module.camera.focusObjectFocus on the Object
e3d.module.camera.saveFocusPointSave Focus point
e3d.module.export.titleExport
e3d.module.export.customModeWarnCan't export while a custom mode is enabled
e3d.module.export.readyReady to export
e3d.module.export.babylonExport .babylon
e3d.module.export.objExport .obj
e3d.module.export.objUpDirOBJ Up Direction
e3d.module.export.readyReady to export
e3d.module.export.exportingExporting
e3d.module.export.invalidExportTypeInvalid export type requested
e3d.module.export.finishedExport finished
e3d.module.geo.addMarkerAdd Geomarker
e3d.module.geo.removeMarkerRemove Geomarker
e3d.module.geo.addAreaAdd Area
e3d.module.geo.removeAreaRemove Area
e3d.module.geo.titleGeo
e3d.module.geo.editorGeo Editor
e3d.module.geo.selectedFenceSelected Geo Fence
e3d.module.geo.selectedControlPointSelected Control Point
e3d.module.heatmap.titleHeatmaps
e3d.module.heatmap.enableCustomThresholdsEnable Custom Thresholds
e3d.module.home.titleScene
e3d.module.home.homeButtonHome
e3d.module.home.noObjectSelectedNo object selected
e3d.module.home.noGroupSelectedNo group selected
e3d.module.label.titleLabel
e3d.module.log.titleLog
e3d.module.outliner.titleOutliner
e3d.module.refImage.titleReference Image
e3d.module.refImage.readyReady for drop
e3d.module.refImage.dndHintDrag and drop a reference image here
e3d.module.refImage.imageWidthHintImage Width (m)
e3d.module.refImage.imageOpacityHintImage Opacity (%)
e3d.module.refImage.refImageReference Image
e3d.module.refImage.clearClear Reference Image
e3d.module.sceneEdit.titleScene Editing
e3d.module.sceneEdit.saveSave Changes
e3d.module.sceneEdit.editModeEdit Mode
e3d.module.sceneEdit.translateTranslate
e3d.module.sceneEdit.rotateRotate
e3d.module.sceneEdit.scaleScale
e3d.module.sceneEdit.snapRotationSnap Rotation to 15 degrees
e3d.module.sceneEdit.duplicateDuplicate
e3d.module.sceneEdit.deleteDelete
e3d.module.sceneEdit.positionPosition
e3d.module.sceneEdit.rotationRotation
e3d.module.sceneEdit.scalingScaling
e3d.module.info.titleInfo
e3d.module.info.versionVersion
e3d.module.info.fpsFPS
e3d.module.info.resolutionResolution
e3d.module.info.cameraCamera
e3d.module.info.positionPosition
e3d.module.info.directionDirection
e3d.module.info.visibleLabelsVisible labels
e3d.module.info.totalLabelsTotal labels
e3d.module.info.hoveredMeshHovered mesh
e3d.module.info.selectedMeshPosSelected mesh position
e3d.module.info.memoryMemory
e3d.module.info.noMeshSelectedNo mesh selected
e3d.module.theme.titleTheme
e3d.module.theme.defaultDefault
e3d.module.theme.blueBlue
e3d.module.theme.lightLight
e3d.module.webxr.titleWebXR
e3d.module.webxr.enterVREnter VR
e3d.module.webxr.leaveVRLeave VR
e3d.module.webxr.notSupportedWebXR not supported
e3d.module.webxr.sslOnlyWebXR can only be served over HTTPS
e3d.module.zoneProfiler.titleZone Profiler
e3d.module.zoneProfiler.zoneProfilerZone Profiler
e3d.module.dev.titleDevelopment tools
e3d.module.dev.incCinematicCamSpeedIncrease CinematicCamera speed
e3d.module.dev.reduceCinematicCamSpeedReduce CinematicCamera speed
e3d.module.dev.updateCameraTransformUpdate camera transform
e3d.module.dev.updateCameraDefaultTransformUpdate camera default transform
e3d.module.dev.transitionToDefaultTransition camera to default
e3d.module.dev.downloadSnapshotDownload snapshot
e3d.module.dev.exportSceneExport scene
e3d.module.dev.incGlobalLightIntensityIncrease global light intensity
e3d.module.dev.decGlobalLightIntensityDecrease global light intensity
e3d.module.dev.geoMarkerTestGeomarker test
e3d.module.dev.logObjCoordsLog selected obj coords
e3d.module.dev.toggleCameraToggle 2d/3d camera
e3d.module.dev.openInspectorOpen inspector
e3d.module.dev.dynamicModuleTestRegister new dynamic module
e3d.module.dev.labelTestLabel test
e3d.module.dev.attachTestLabelAttach test label
e3d.module.dev.fakeXREntryAndLeaveFake XR entry and leave
e3d.module.atlasDebugger.titleLabel atlas debugger
e3d.module.atlasDebugger.atlasesAtlases

Modules

Scene

Imgur7

The scene module displays three elements

  • Home button. Clicking the button triggers the following
    • TransitionCameraToDefault service
    • HomeClicked event
  • Selected object field. This field will display the name of the mesh or alternatively a custom text that can be bound the mesh through label data. Clicking on the field when an object is selected will trigger the following
    • TransitionCameraOnSelectedObject service
    • ObjectClicked event
  • Selected group field. If the selected mesh belongs to a group, the name/id of the group will display in this field. Clicking on the field when an object is selected will trigger the following
    • TransitionCameraOnSelectedObject service
    • GroupClicked event
    • A property update updating the SelectedObjectId to the group id

Camera

Imgur8

The camera module presents the user with various camera related buttons:

  • Add waypoint button that can be used to place waypoint(s) in to the current scene, allowing a camera flythrough to be performed. When the Add Waypoint button is clicked, a waypoint is added at the current camera location. Thus, before adding a waypoint, position and orient the camera to a place where you want to flythrough to go through.
  • Remove waypoint button that will remove the waypoint that was added last
  • Save waypoints will trigger the UpdatePathAnimation service that will serialise the current waypoints to a JSON format, finally triggering the CameraPathUpdated event once the serialisation is finished
  • Flythrough button will start a camera flythrough in the current scene using the defined waypoints. If no waypoints have been set, clicking the button does nothing but trigger the StartPathAnimation service.
note

It is up to the developer to save the modified waypoints somewhere if persistency is wanted. Otherwise the waypoints will be gone after a refresh. To save the waypoints, save the data stored in CameraPath property when the CameraPathUpdated event is triggered

Heatmap

Imgur9

Geo Editor

Imgur10

Label

Imgur11

The label module will allow displaying the data bound to a label within a module.

Annotation

An annotation is an 3D object.

  • It is a tiny 3D mesh that is invisible to human-eye. It is created by the users through the annotation module, or through the AnnotationData.
  • The intuition of the annotation is that the label must be bound to an 3D object. In case there is no 3D objects at a coordinate, an annotation can be used as an anchor for that coordinate.
  • An annotation has another visual label bound to it (what we call annotation icon). Since an annotation is just a tiny 3D mesh, an icon is useful to visually identify the annotation.

ImgurAnnotation1 ImgurAnnotation2 ImgurAnnotation3 ImgurAnnotation4

The annotation module will allow to add/delete annotation. It can also used to edit the information of an existing one.

Double-click on an existing annotation to enable the edit mode.

Theme

Imgur12

The theme module allows a user to set their preferred theme for the GUI, the selection is stored in the localStorage of the browser meaning that it will only be apply for a single machine.

An example of the currently available themes can be seen below

 Imgur13
Default theme
 Imgur14
Blue theme
 Imgur15
Light theme

Stats

Imgur16

The stats (info) module is a handy tool for a developer to view various statistics and information of the current scene. Currently the stats module lists the following stats:

 StatDescription
FPS Frames-per-second shows how many frames the viewer can render at the current time.
NOTE: The FPS can be limited by the browser/monitor
Resolution Current rendering resolution of the canvas. By default the rendering resolution is not limited and equal to the size of the canvas but it can be controlled with the CanvasRenderingWidth and CanvasRenderingHeight properties 
CameraThe name of the camera that's currently in use. Can be one of the following depending on the situation: mainCamera, sidescrollingCamera or cinematicCam
PositionWorld position of the currently active camera
DirectionView direction of the currently active camera
Visible labelsCurrently visible labels within the scene, update on at least these labels will be handled whenever an UI update is needed
Total labelsTotal number of labels within the scene, this number contains all the labels that are either hidden (by layout or due to belonging to a group) or are currently outside the camera frustum
Hovered meshName of the mesh that's currently under the pointer or None
Selected mesh positionWorld position of the currently selected mesh
MemoryCurrent javascript heap usage

Zone Profiler

Imgur17

The Zone Profiler module can be used to record and spot performance issues and other long running tasks within the viewer or even outside of it. The module is only available when the DebugMode is enabled and will record up to 240 frames worth of data.

In the image above, we can see that the viewer's taken a most 2.22ms to update within the last 240 frames, where as something between the frames (viewer updates) has taken up to ~67ms. In this example, the long running task was executing a heavyish ThingWorx service every second

caution

The zone profiler is still a work in progress and can currently only be used to visualise the frame times

Usage Example

In the following example we will start by having a look at the example mashup that is included in the Elisa3DViewerModel_ExtensionPackage and continue by recreating some of that functionality to a fresh mashup.

info

In this documentation, we will only look at Elisa3DViewer.Mashup.Example1. Other examples might demostrate different capabilities of 3DV. Make sure to check them out as well!

Example 1 - Robot example

Example 2 - Moving objects example

Example 3 - Physically based rendering example

Example 4 - Annotation and label example

Let's start by having a look at the example mashup named Elisa3DViewer.Mashup.Example1 and viewing it

Imgur18

You should be presented with a view similar to this

Imgur19

Immediately the view presents you with some of the basic features of the 3d viewer:

  • It shows the default Modules (GUI) on the left (1)
  • Two different types of labels; a single collapsed label (2) and a collapsed group label (3)
  • Two of the assets are displaying (abnormal) states (4)
  • Three geo fences (5)

If you move your cursor around the scene, you can see some of the assets within the model displaying a highlight around them during hover. This means that the hovered asset is selectable, allowing you to define a view (or a focus point) for that specific asset. When an asset has a focus point defined, selecting that asset will transition the camera to the predefined view thus showing the asset from a point-of-view of your choosing.

note

Selecting such an asset and transitioning to the new view will most likely move the focal point of the camera meaning that rotating around the whole scene might not work properly anymore. In such a case you can always click on the Home button to reset the view back to its initial position.

When you happen to hover either the lollipops (collapse labels) or the assets they're attached to, you can see label opened if it was collapsed. In the image below on the left you can see a single label displaying various dummy KPI's and information and on the right you can see a group label displaying states and titles of its sublabels. This kind of content for the group label is automatically generated when the labels are grouped, but you can also define your custom content for the group labels the same way as you would do for the normal labels. We will see how to do this later.

Hovering the group label also displays a rough bounding box that should contain all the assets that belong to that group.

Imgur20
Hovering an asset will display a highlight around the asset and the attached label expanded

Moving the camera

By default the 3d viewer uses an arc rotate camera (also known as orbit camera) which allows you to rotate the camera around a specified target. Controlling the camera is done using a mouse. Dragging the canvas with the primary mouse button will rotate the camera around its focal point. Dragging the canvas with the secondary mouse button will pan both the focal point and the camera. We will come back to this later when we build the mashup from scratch and use the debugging mode to visualise the focal point. Alternatively if you wish to present a scene somewhere without having to move the camera manually, it is possible to define waypoints for the camera and have it automatically fly through the waypoints displaying. The example mashup has predefined waypoints that will showcase the example model. You can enable this mode by clicking on the Flythrough button that's inside the Camera module in the left. After clicking on the Flythrough button the viewer will take over the camera and switch to a camera called Cinematic camera. When in mode, you can't control the camera but can still interact with everything as usual. To exit the flythrough mode, you can either click on the Home button or by selecting (double clicking on) an object that has a "focus point" defined. In the example scene all selectable assets have a defined focus point.

Selecting an object

There are three ways to select an object:

  • By double clicking on the actual asset
  • By double clicking on an attached label (if one exists)
  • By setting the SelectedObjectID property

When you select an object, its name appears in the Scene modules object field (1). If the object belongs to a group, the group will also be selected and shown in the group field (2). While labels can have different layout modes/states depending on whether they're hovered, belong to a group or anything, when the asset with a label is selected, that label will use the full layout mode (3) and appear on top of every other label no matter the distance. Should the object belong to a group, every object not belonging to the same group will be hidden if ShowOnlySelectedGroup is enabled (4).

Imgur21

Labels

One way to visualise data in the 3d view is the usage of labels. The 3d viewer has two different types of labels; regular and group labels. For the most part these two labels are the same, except a group label can only be created by assigning regular labels to a group. When a label belongs to a group, it will be hidden until either the group is selected or the asset its attached to is hovered. Grouping labels can help you organise parts of the scene into smaller logical sections. By default the contents of a group label is automatically generated and it will display the labels belonging to the group ordered by their state.

Imgur22

It is also possible to define custom content for a group label the same way as you would for a regular label. We will have a look at how to do this when we create the mashup from scratch.

The contents of a label consists of entities that we refer to as KPI's here (Key Performance Indicator) even if they are not necessarily KPI's. The list below shows the possible contents of a label

  • Title of the label (1)
    A label can consist of two titles, the regular one shown in the picture above and a collapsed title which is shown when the label is in its collapsed state, e.g. no KPI's/content is shown.
  • Progress KPI (2)
    A progress kpi is a simple progress bar that consists of a title, value and min and max values. In the example
  • Key-Value KPI (3)
    A simple key-value pair displaying a title and a value in text format
  • Custom Info KPI (4)
    Any text without values, can be useful to display machine statuses or other messages
  • Speedbar KPI (5)
    Speedbar is similar to the progress KPI but more expressive with its three possible ranges (red, orange, green). The ranges are defined using two limits. Also displays the title and value
  • Speedometer KPI (6)
    Like speedbar except for its visual representation
  • State of the label (7)
    The status icon can give a quick indication of whether everything's running normally or if there are any anomalies happening. The status icon is shown in all other states of a label except when it fully hidden

Imgur23

Building an example mashup

caution

This example was built using ThingWorx 8.4.1-b2126 so your view(s) might look different depending on the version you are using.

Getting started

The easiest way to get familiar with everything is to just use the extension and do things with it. So let's create a simple mashup with some of the functionalities of the Elisa3DViewer.Mashup.Example1. Start off by creating a new mashup, we'll use a Responsive (Advanced) layout here and select Header Only template as we'll be placing some ThingWorx widgets there.

info

If you are running an older version of ThingWorx (the version here is 8.4.3) and the Responsive Advanced - Header Only is not available, you can always just create a normal responsive mashup and place a layout widget with a header row

Imgur24

Give the mashup a name of your choosing, click Save and enter Design mode.

Imgur25

Next up look for the Elisa 3D Viewer widget under the Widgets tab on and drag and drop it to the main area of the mashup container. When done right you should see the widget filling up the available space and a white logo in the middle as in the image below.

Imgur26

Now if you save and view the mashup, you should already see the viewer initialising a bit by first loading its scripts and finally stalling at "Waiting for scene". This means that everything's working as expected and the widget is waiting for a scene to display, we'll do that next by using the example dataset that's installed with the Elisa3DViewerModel_ExtensionPackage as an example to generate some data for the viewer.

Imgur27

Binding data to the widget

To get something showing in the viewer, we need to provide it with at least the scene to load. Currently the scene needs to be provided through a property update as the viewer doesn't check for hardcoded values in the SceneModelURL during startup. Let's continue by creating a new thing. Set the Base Thing Template to GenericThing and selected Elisa3DViewer.TShape.ViewerDataset as an implemented shape. After saving you can see that the ThingShape has provided our thing with some basic properties and services to get started.

note

There's no need to use the provided ThingShapes and other examples, but we'll do it here to make everything a bit easier

Imgur28

Click on the Properties and Alerts and look for the sceneUrl property. Edit the property and give it the following value /Thingworx/Common/extensions/{PACKAGE_NAME}/ui/Elisa3DViewer/models/PTC_Robot.babylon. This value is for the same model that is displayed in the example mashup we looked at earlier and the value can be found in the Elisa3DViewer.Dataset.Example1 thing. The {PACKAGE_NAME} part of the value is something that gets parsed by the viewer during runtime, allowing the examples to continue working properly even if changes were made to the name of the extension.

Switch back to the mashups' design view and click on the + icon on the right side under the Data tab to add a data binding to our dataset thing we just created. From the popup find your thing using the Search entities functionality. After selecting the entity just search for the GetProperties service and click on the little arrow to add the data binding to our mashup, also check the Mashup Loaded? checkbox to have the service execute after the mashup has been loaded, thus we don't need to trigger it ourselves. Click on Done and you should see the service listed in the container inside the Data tab.

Imgur29

Now we can actually get something to show up in the viewer when opened. Expand the GetProperties service and look for the sceneUrl property and drag and drop it on top of our widget in the mashup builder. This will prompt you with the properties you can connect the data to, look for the SceneModelUrl in the list and select it. If you've done everything correctly you should have connected the sceneUrl from the GetProperties service to the SceneModelUrl of the widget. You can also see this in the Connections tab at the bottom of the mashup builder. Now if we save and view the mashup, you should see the scene from the example mashup loading up without any labels or such things.

caution

If you made any changes (added or removed) to the modules when looking at the example mashup, those settings should've been saved to your localStorage and the modules should show up how you left them. E.g. in the image below, Info and Heatmaps modules were added

Imgur30

Imgur31

Orbit camera and camera waypoints

Before moving into the more ThingWorx related things, let's have a look at the orbit camera using the DebugMode and also how to specify and save waypoints for the camera flythrough. To do this we need to modify the mashup a little bit, by enabling the DebugMode we get a few more buttons to the Camera module (as seen in the module section). Set the DebugMode property to true. This will allow us to define the waypoints and test the functionality, but without connecting it back to ThingWorx, that data doesn't persist between users/sessions. Thus we'll add the SetProperties service to the previously bound Thing under the Data tab in the mashup. Then if you expand the SetProperties, the property cameraPath is what we need to bind our waypoint data to. The property from the widget is called CameraPath and you can drag and drop it to the cameraPath param in the SetProperties section. Again you can verify that the connection was made by checking the Connections tab at the bottom.

Now that the property is bound back to the thing, we still need to actually save it. This can be done by binding the CameraPathUpdated event from the widget to the SetProperties service, thus when the CameraPathUpdated event is triggered, the SetProperties will be called and it will update the cameraPath property from the widget's CameraPath property. This can be done either from the dropdown menu or by searching for the property in the sidepane. Finally to actually load the camera path back to the viewer, you need to connect the cameraPath property from GetProperties back to the CameraPath of the widget.

Imgur32

Imgur33

Imgur34

Imgur35

info

When loading the camera path back to the widget, you might notice that the debug visualisation of the path is missing. This can be caused by the path being set before the scene has loaded and the viewer disposing of all existing meshes before loading a new scene. In such a case the actual flythrough should still work but the debug view doesn't. To fix this, add another data binding to the Thing and call its GetProperties after the widget has triggered its ModelLoadDone event.

Imgur36

Now if we view the mashup, you should see the following additional buttons in the Camera module; Add Waypoint, Remove Waypoint and Save Waypoints so let's test it. Move the camera to a location and view that you want to see in your flythrough and click on the Add Waypoint button, then move the camera to another location and view and click on the Add waypoint button once more. Now you might notice something appear in the view that's partially blocking the view, this is the debug view of the camera path drawing itself allowing you to have a look at the flight path the camera will take when running the Flythrough mode. Add a few more points and zoom out to have a look at the generate path. If you click on the Flythrough button now, you should have your camera first move to the closest path point and start moving through the defined waypoints by following the white ribbon. Finally when you click on the Save Waypoints button, the viewer will generate a JSON string of the defined path, store it to the widget's CameraPath property and trigger the CameraPathUpdated event. If you've done all the connections described above, you should now be able to refresh the page and have your waypoint persist. You can also verify this by having a look at the cameraPath property from the thing itself.

info

The cones and white ribbon displaying the flight path are only visible when DebugMode is enabled

Imgur37

Let's have a quick look at how the DebugMode might help us understand how the camera works a bit better. If you have enabled the DebugMode and pan the camera to the side enough so that the focal point is not in the middle of the model, you should see a white sphere appear. This sphere is actually the focal point being visualised, now if you rotate the camera you should see that the camera rotates around the sphere and when you pan the camera, the focal point remains centered to the camera's view. When zooming closer to the sphere you notice that the zooming stops really close to the sphere as it doesn't allow the camera to move through the focal point. This point is always present with the orbit camera, even if not visualised, and acknowledging it might help you understand how to work with the camera. In the example mashup when you selected an asset and the camera was moved to a view where the asset was in focus, what actually happened was that the camera panned and rotated in such a way, that this focal point was approximately centered to the asset that we wanted to view.

Imgur38

Attaching labels

To display KPI's and other relevant information in the scene, we can create and attach labels to each asset in the scene. While still in the viewer, we need the name/id of the asset we want to attach a label to, so let's select any one of the assets by double clicking on it. This will display the needed ID in the Scene module. Here we've gone with the PTC_Robot_Station_2

note

Selectable assets display a highlight around them when hovered. Also a label can be attached to assets/meshes that are not selectable by default if you know their ID/name.

Imgur39

With the name of the asset let's open our DatasetExample thing and edit its LabelData property and from the popup click on Add to insert a new row in to the Infotable. From the popup let's fill in just the basics for now to get something showing. Pretty much all we need to get anything showing is the objectId and id, but only using the two would result in an error label so let's fill in the following fields for now:

  • objectId - Name of the asset we looked up in previously
  • id - Some unique identifier for the label, this can be used later to refer to this label
  • title - Title text for the label, for now title is the only content we'll give to our label
  • state - State of the label, let's set this to 0 for now and have a look at why in a bit. If we leave this empty, the label will get an error style

Everything else can be left as is.

Imgur40

Imgur41

Now to get the labels showing, we need to modify our mashup a bit and connect the LabelData to the widget. There's actually a service within the ViewerDatashape ThingShape we used to implement the thing called GetLabelData which we'll use. At this point you can connect the labelData property directly from GetProperties to the widget's LabelData, but we'll use the provided service as we'll be overriding some of its functionality in a bit. So add the service GetLabelData to the data binding and connect its AllRows output to the LabelData property of the widget. If you take a look at the label fieldname properties from the widget's property list, you should see that most all of them are automatically populated with the correct fields. If you're using your own DataShapes, you might need to configure the properties here to match your setting. Now let's also configure one property called LabelStyleStateFormatting, this will be used to set a correct state (style) for the label. To configure the formatting:

  • Click on the State Formatting button next to the property name
  • In the popup select State-based Formatting
  • Set Dependent Field select to state (NOTE: For the fields to show up, you need to have connected something to LabelData)
  • From the State Definition field search for Elisa3DViewer.States.Labels and select it
  • This will list you all the possible states for our labels and their state values. Finally click on done
tip

You can also play around with your own state definitions

Imgur42 Imgur43

Imgur44

If you had a look at the different state-value pairs in the definition, you might've noticed that state 0 is used for Not Configured which is what we can expect to see once we open the mashup as we defined the state of our first LabelData to be 0. Now save and view your mashup, if you've done everything right you should see a lollipop with the Not Configured icon on top of your selected asset and hovering it or the asset should display the label with its title showing.

Imgur45

Before we start looking at the other possible options for labels, let's make the mashup update the label data periodically so that we don't need to refresh the whole mashup whenever we make a change to the label data. To do this, add a Auto Refresh widget to the mashups header, make sure that AutoRefresh is enabled, set the RefreshInterval to something like 5 and connect the Refresh event to our Thing's GetLabelData service. This will make the GetLabelData service execute every 5 seconds thus updating the viewer with any updated label data. To test it out, save the mashup and view it again, now go to the DatasetThing's properties and edit the label data and set the state from 0 to 2. If everything's up and running correctly, you should see the state of the label switch from Not Configured to Running without needing to refresh the mashup runtime anymore. Now we can start adding more data to our label and see the updates being almost immediately reflected in the viewer.

Imgur46

Imgur47

Let's go back to editing the label data in our dataset thing; we skipped some of the properties at first so let's have a look at them;

  • collapsedTitle - Is shown when the label is in a collapsed state but due to layouting, has its title shown. Set some value to this field to see it in action
  • text - This field is here for or less just backwards compatibility, but in case you want to display a label with just some text, this might be the quickest field to do that.
  • group - The group field allows us to group labels and assets, leave empty for now as we're only working with one label
  • animationMode -
  • layoutMode - Layout mode is used to control the initial layout of the label (e.g. when not selected or hovered). Possible options are
    • 0 - Hidden, the label is hidden by default. Hovering/selecting the attached asset will display the label normally
    • 1 - Collapsed, the label will only show its state (lollipop)
    • 2 - Title, similar to collapsed but also shows the label's title when not hovered/selected. (NOTE: Using this layout will display the label's collapsedTitle or title, whichever is present in that order)
    • 3 - Full, display all the label data even if not selected/hovered
    • 4 - Reserved, currently the same as Full
    • 5 - Default, will alternate between Collapsed and Title layouts based on the distance to the label. E.g. labels close enough to the camera will display the title, where as labels further away will only show the lollipop
  • kpiData - Kpi data allows us to present various KPI's and other data in the label

Imgur48

For now let's just set some value to collapsedTitle, change the layoutMode to 2 (to see the effect of collapsedTitle and add some kpiData. To do this click on Add button next to the kpiData property. This will open up another popup with some more fields, before we fill in anything here's a list of the fields and what each one does:

  • title - Title of the kpi, this should be present for all kpi types
  • value - Value of the kpi is used for every kpi type except for Custom info
  • type - The of the the kpi, the following types are supported:
    • 0 - Custom info kpi will only display the title, useful for presenting asset status and other messages
    • 1 - Key-value pair kpi will display the title and value next to each other in text format
    • 2 - Progress kpi will display a progress bar from min to max with the value as progress (the bar clamps to min and max, e.g. doesn't overflow)
    • 3 - Speedometer kpi displays the value in both text format and as a indicator in a speedometer. Speedometer also uses limits (and lowerLimit if defined) and can be inverted. By default the "good" values are before the limit is hit (e.g. the first half), to make higher values better tick the inverted checkbox
    • 4 - Speedbar kpi is similar to speedometer but displays the value in a progress-like visual format. Speedbar also uses limits (and lowerLimit if defined) and can be inverted. By default the "good" values are before the limit is hit (e.g. the first half), to make higher values better tick the inverted checkbox
  • min - Minimum value for the kpi, this is needed for kpi's that have a specific range (progress, speedometer and speedbar).
  • max - Maximum value for the kpi, this is needed for kpi's that have a specific range (progress, speedometer and speedbar).
  • limit - If there's a limit for the KPI, e.g. after (or before) which the kpi is considered to go from good to bad (or vice versa). Applies to speedometer and speedbar.
  • lowerLimit - If there's a need for an intermediate stage, set a value for the lowerLimit, this will display a third state for the KPI's in yellow ("warning"). Applies to speedometer and speedbar.
  • id - Used to identify the KPI.
  • inverted - Whether the range should be inverted or not (e.g. values below limit should be considered bad). Applies to speedometer and speedbar.
  • state - Similar to states for the label but for individual KPI's instead. Used to colour the title/value etc based on the state.

Fill in the kpiData with kpi's of your liking, for the example we'll create one or more of all KPI's to showcase them.

Imgur49

In the end, your kpiData might look something like this (NOTE: You can also construct the kpi data programmatically in a service or by querying connected assets)

Imgur50

Now if you save the labelData property and have a look at the mashup, you should see the KPI's appear in the label. You might notice that the text's for the KPI's are shown in red, this happened because we didn't specify state formatting for the KPI's and the returned state when the viewer queried it was an error style, in which the text colour is set to red. To fix this, let's open up our mashup builder and do the following:

  • Under the GetLabelData service in the data bindings window, expand the AllData under Returned data and drag drop the kpiData to the widget and connect it to the KpiData property. NOTE: This binding is not actually used for connecting data, but rather to give the viewer a knowledge of the used DataShape so that we can configure the KPI fields and states properly
  • If you're using the DataShape from the example, all the field name properties should be automatically configured. If not, you should look for properties starting with "kpi" and configure the field names to match your setup.
  • Look for the widget's properties starting with "kpi" and configure the KpiStyleStateFormatting the same way as you did for the label. Now if you save and refresh your mashup, you should see the kpi's and their texts colored properly. (NOTE: You can only control the colour of the texts and the progress kpi using the states. By default the KPI's will use the Background color of their state, but this can be configured using the KpiFontColour field. If you don't do this, all the KPI texts will most likely show up with a dark grey colour and not necessarily reflect the actual state of the KPI.)

Imgur51