How to apply a generic array comparison expression binding

I'm trying to create an expression binding where compares the text in '.label' from an array equals a certain string it changes the color of the object binding.

It works fine if I define an array number, but I want to dynamically apply it to all events in the array as items are deleted and added to the array structure.

Example:
IF({this.props.scheduledEvents[0].label} = "TEST", '#6ECEB2', '#FFBE9F')

Is there a way to do what I am trying to achieve?

There is no iteration in base Ignition expressions. The Integration Toolkit (free) from pturmel adds this capability.

Would a Map Transform | Ignition User Manual do what you want?

In your case set the Input Type: Value and Output Type: Color. Enter the strings you're testing for in the values column.

How are you displaying all these events? Flex repeater? If you can, show us an example of how your view is set up.

Is this binding on the root container? or the base view?

The events are being displayed on a EquipmentSchedule component.

This binding is on the root container.

Hi Everyone,

I worked out how to implement this.

I added a transform script on the 'props.scheduledEvents' of the Equipment Schedule component binding itself.

Process:

  1. Loop over each event.
  2. Copy it (dict(e)).
  3. If .label == "TEST", set ["color"] = "#6ECEB2"; otherwise, set a default.
  4. Append the copy to a new list.
  • Output: Return the new list. Each event now has its own "color".
  • Outcome: The component (e.g. the Schedule) automatically consumes that "color" field to render events with the correct hex code.

def transform(self, value, quality, timestamp):
	# Transform script for property binding. Assume "value" is the incoming array of event‐objects.
	events = value  # e.g. [{ "itemId":1, "eventId":16, "label":"TEST", ... }, {...}, ...]
	
	# We'll produce a new list, so that each event gets a "color" attribute based on its label.
	out = []
	
	for e in events:
	    # Make a shallow copy so we do not overwrite the original
	    newEvent = dict(e)  
	
	    if newEvent.get('label') == "TEST":
	        newEvent['backgroundColor'] = "#6ECEB2"
	    else:
	        # either leave it blank or give it a default color
	        newEvent['backgroundColor'] = "#FFBE9F"
	
	    out.append(newEvent)
	
	return out

Hope this help's anyone else.

2 Likes

Likely unimportant performance consideration: You don't need to worry about making a copy of the original list, you can edit the original without concern. Nothing else is touching or using the original list.

I'll suggest this:

color_map = {
	'TEST': '#6ECEB2',
	'FOO': '#AAFFEE',
	'BAR': '#443322'
}
default_color = '#FFBE9F'
return [
	dict(
		event,
		backgroundColor = color_map.get(event['label'], default_color]
	) for event in value
]

Simply configure your label -> color map, and pick a default color.

1 Like

Depending on the source of the data, the e might be immutable, in which case he does need to build a new dict to be able to add the backgroundColor key.

Good point

Consider, having the color map as a separate custom property, and reference that from the script transform. Much more visible and you don't have to edit the script transform to make small tweaks or add items

Yes that's not a bad idea.
Could be used to make the color map dynamic.
It also allows other properties to use the same colors.
But then he should use a structure binding, to bind on both the original data and the color map.

If it doesn't change much, and it's only used by that transform, I'd stick to a simple color map in the script.