Expression vs Expression Structure Relative Position Binding Ignition 8.1.31

I have 2 labels in the root Coordinate Container of a small Perspective view (233w x 400h), which will be used as an embedded view. There are other items in the view, but the goal is to change the y position of the first label depending on the value of a string parameter (e.g. if view.params.selector is A, then label1.position.y = .2), then adjust the position of the second label offset from the first label.

I've found that any hardcoded value in the Script transform of an expression structure binding

def transform(self, value, quality, timestamp):
	if value.type == 'A':
		return 0.7367
	elif value.type == 'B' or value.type == 'C':
		return .8867
		return 1

), and any relative calculation in an expression binding
{../Label.position.y} + .0541
) display as expected in the embedded view in a perspective page. However, when I use the same label1 position in the Script transform of an expression structure binding

def transform(self, value, quality, timestamp):
	if value.type == 'A':
		return float(self.getSibling("label1").position.y) + .1209
	elif value.type == 'B' or value.type == 'C':
		return float(self.getSibling("label1").position.y) + .0441

), label1's position must evaluate to 0, because label2's position reflects the offset value only.

There have been times when the development environment showed the correctly calculated position, and only the browser showed the wrong one, but now it's consistently wrong in both places. Although using the expression binding is a work-around, I prefer the readability of the python if statements.

Is there a way to modify the expression structure script to make sure I capture label1's position after its binding has executed?

The whole point of a structure binding is to bind to everything that must be monitored.
From what you posted, you're only binding to one thing, that you called type.

You could add an expression to that structure binding, call it label1_y, and bind it to label1's y position, then use that in the script, you should be fine.

Can you share your view's json ? I think there's a better way to do this.

Can you clarify your statement on the structure binding? I am fairly new to Ignition, so I didn't have a really detailed reason to use any particular binding, besides preferring python for its visible "else" statement in this case, as opposed to following commas and parentheses in expression language. Are you implying that if I pass in one incoming value, that it's more efficient for that value to be a structure/dataset itself?

That ended up working, assuming you meant that I could pass in the position as another incoming value. Functionally, what does passing the value in through the incoming value do, that directly accessing the property value doesn't?

I don't know if I'm allowed to do that in this moment. Is there something specific you're looking for? If it helps, I'm not trying to animate this position change, I just don't see a need to create more than one view to embed, when the difference I'm trying to reflect only affects the text and/or position of a few simple components.

Structure bindings don't have anything to do with python. Any type of binding can have a script transform.

While a regular binding binds to one thing, structure bindings can bind to several.
Bindings are reevaluated when their source changes, for example a property binding will be evaluated every time the property it references changes.
Now, let's say you have 2 properties foo and bar. If you use a property binding to foo, then add a transform in which you reference bar, the binding will only ever reevaluate when foo changes. Not bar.
Now, if instead you use a structure binding, with 2 incoming values, one bound to foo and the other to bar, this binding will reevaluate every time either foo or bar changes.

Don't. You're making that view more complex than it has to be, and frankly that's never a good idea.
Now, this thread is tagged with perspective. This doesn't look like something very perspective-y, there must be a better way of having just one template without doing all this funky stuff. Which is why I was asking for the view, it's hard to go any further without more details.
Make a copy of the view, remove anything related to your company, then send the view's json.
Frankly, maybe ask first, but I can't see any reason they might be mad about you sharing a few empty labels.
I'm looking for why the labels need to move so precisely through complicated bindings.

1 Like