Community Tip - Want the oppurtunity to discuss enhancements to PTC products? Join a working group! X
Hello. I'm trying to implement a dashboard in Vuforia Studio which contains several 3D labels which are connected to real-time information through Thingworx Composer.
I'm interested in applying State Formatting to the 3D labels. My use case is this: I have a value that represents the production quantity, and a boolean property which indicates whether the production is on target or not. I'm interested in binding the value to the 3D label and apply state formatting through another property (the boolean value). This can be perfectly done in Thingworx's Mashups.
In Vuforia Studio, however, if I enable State Based Formatting for a label, I have a Dependent Field, and I can choose which State Definition to apply to it. If I leave the Dependent Field value as default ("text"), then it compares the actual text-value of the 3D label to the values that are inside the State Definition, and then applies the corresponding colour. This is not what I need, because I need to apply State Formatting through the boolean property.
So I tried binding said property to the Dependent Field, but the colour of the 3D Label is the one shown in the Default state. I went with my intuition, and removed the value binding of the 3D Label text, and replaced it with "true". And, as I anticipated, the label turned green.
The conclusion is that the Dependent Field property inside the State Formatting compares the actual String value attached to the 3D Label to the State Definition values INSTEAD OF comparing the bound property value (which in my case, is a boolean property) to the State Definition values.
In Thingworx, it is possible to change the colour of a Value Display through a boolean property, and still be able to display the number.
In the screenshots below, you can see the 3D Label number being blue when I tried binding the isOnTarget property to the Dependent Field, because it compared 33 to "true" and "false", they don't match, and goes into default colour, which is blue.
actualGreen shows when the number binding is removed and replaced with a static "true" string, it matches the "true" in the State Definition, so it shows green.
I also attached the State Definition, which turns the text green if true, red if false, and blue for default.
Has anyone worked with Vuforia State Formatting before and can lend me a hand in this problem?
Solved! Go to Solution.
additionaly for state based fromating you review the following posts:
Using Connection Filters for state-based rendering and value formatting
One of the ways when you try to use state based formatting would be to use a different property for the state format comparison (because the value you try to check and the value for the display are different), and then bind the value from the data to both the new property and to the display value. The display value still gets the filter to add the units, but the other value keeps it as-is.
So for example for gauge the value to a new hidden property:
setWidgetProp('gauge-1', 'hiddenValue', value)
And then set the dependent field to be 'hiddenValue':
setWidgetProp('gauge-1', 'stateFormatValue' 'hiddenValue')
Hi @Radu,
I did notice that the state does not honour the value of "Dependent Field" when "Dependent Field" is bound to other property (not based on 3D label text). Hopefully someone from technical support can solve the mystery.
As a workaround, it is easy to achieve your requirement through code (without state formatting).
You can define an application parameter to hold your boolean property value. In the following code sample, I called it "BooleanProperty". Replace "3DLabel-1" with your 3D label widget name.
$scope.$watch('app.params.BooleanProperty', function(val) {
switch (val) {
case "true":
$scope.view.wdg['3DLabel-1']['fontColor'] = "rgba(0,255,0,1)";
break;
case "false":
$scope.view.wdg['3DLabel-1']['fontColor'] = "rgba(255,0,0,1)";
break;
}
$scope.$applyAsync();
});
Hope this helps.
Hi Wilson,
Thank you for your provided solution. This fixes the state formatting. However, when I try and change the isOnTarget property on the Thingworx side, the colour doesn't change until after a refresh.
Is there any way to force this colour change in real time?
Thank you!
additionaly for state based fromating you review the following posts:
Using Connection Filters for state-based rendering and value formatting
One of the ways when you try to use state based formatting would be to use a different property for the state format comparison (because the value you try to check and the value for the display are different), and then bind the value from the data to both the new property and to the display value. The display value still gets the filter to add the units, but the other value keeps it as-is.
So for example for gauge the value to a new hidden property:
setWidgetProp('gauge-1', 'hiddenValue', value)
And then set the dependent field to be 'hiddenValue':
setWidgetProp('gauge-1', 'stateFormatValue' 'hiddenValue')
here to my last comment you can check also the posts:
Problem with the change the color gauge 3D twx studio /GAUGE 3d
Hi @Radu ,
one option you c an try is in the solution code to replace:
$scope.view.wdg['3DLabel-1']['fontColor'] = "rgba(255,0,0,1)";
by $scope.setWidgetProp e.g. :
$scope.setWidgetProp(3DLabel-1','fontColor, "rgba(255,0,0,1)");
Hi
Thank you for your help. Even though this solves the state formatting issue, the colour is not updating in real time. Meaning that if I change the value to make it off target, the colour stays the same as before, only if I refresh the whole experience, then it changes. Any idea why?
Hi @Radu ,
in generally may be two possible options:
1.) after setting of property call $scope.applyAssync();
2.) set a value to an application parameter and bind the parameter (if required using filter) to the property
In this case in the javaScript you will set the application parameter - which will update the property via the binding
Hi.
Thank you for responding. My code is the following:
$scope.$watch('app.params.isOnTarget', function(val) {
switch (val) {
case "true":
$scope.setWidgetProp('3DLabel-2','fontColor','green');
break;
case "false":
$scope.setWidgetProp('3DLabel-2','fontColor','red');
break;
}
$scope.$applyAsync();
});
Notice the $scope.$applyAsync(); at the bottom. However, the colour doesn't update in real time, but the value of the 3D label does. Am I doing something wrong?
What I meant was something like this:
But to be sure if it work I tested it and work only one time but as you mentioned it will not update:
It seems that this will in generally not work for the frontColor of the 3DLabel widget. The property will not update when we change the value. For all properties such should update the color. I have no Idea why this not work here
As workaround/solution you can define a css style and used it to change the apperance of the 3D label widget:
So, here I defined in the Application section /app.scss the following classes:
.my-green {
font-family: Century Gothic;
color: white;
background-color: green;
font-weight: bold;
font-style: italic;
}
.my-red {
font-family: Century Gothic;
color: white;
background-color: red;
font-weight: bold;
font-style: italic;
}
I used here a button classes /not optimal but should only demonstrate the issue
And your code was updated to :
$scope.$watch('app.params.isOnTarget', function(val) {
switch (val) {
case "true":
//$scope.setWidgetProp('3DLabel-2','fontColor','green');
$scope.setWidgetProp('3DLabel-2','class','my-green');
break;
case "false":
//$scope.setWidgetProp('3DLabel-2','fontColor','red');
$scope.setWidgetProp('3DLabel-2','class','my-red');
break;
}
$scope.$applyAsync();
});