[SOLVED] Add alternating color to Perspective table rows through scripting after sorting the data

I have a generic Perspective table with an added custom property called ds that will call a named query in the future.

On the table is a single system event onStartup that calls a custom method script on the table.

image

That custom method completes the following code:

def colorRows(self):
	value = self.custom.ds
		
	# Initialize variables
	new_list = []
	is_light = False  # This variable will keep track of the current row color

	# Iterate over each dictionary in the original list
	for item in value:
		row_color = "tables/rows/green/"

		if is_light:
		    row_color += "light"
		else:
		    row_color += "dark"
		    
		new_dict = {
		    "city": {
		        "value": item["city"],
		        "editable": True,
		        "style": {
		            "classes": row_color
		        },
		        "align": "center",
		        "justify": "center"
		    },
		    "country": {
		        "value": item["country"],
		        "editable": True,
		        "style": {
		            "classes": row_color
		        },
		        "align": "center",
		        "justify": "center"
		    },
		    "population": {
		        "value": item["population"],
		        "editable": True,
		        "style": {
		            "classes": row_color
		        },
		        "align": "center",
		        "justify": "center"
		    }
		}
		
		# Append the converted dictionary to the new list
		new_list.append(new_dict)
		
		# Change every other row of color.
		is_light = not is_light
	
	self.props.data = new_list

On system startup the code works fine.

But when I go to sort any columns the color of the lines are now wrong.

What event do I need to look for on the table to trigger re-coloring the rows after sorting them? None of the obvious answers appears to work.

Thank you for any advice.

This is a good use for CSS and styles rather than assigning the color in a script. The browser would manage alternating the background color and sorting wouldn't be an issue.
The default Perspective table seems to use css classes ia_table__body__row--even and ia_table__body__row--odd.
If you don't mind a sledgehammer approach, you could add the following to Styles/stylesheet.css

.ia_table__body__row--even{
	background-color: blue;
}

.ia_table__body__row--odd{
	background-color: yellow;
}

Any HTML color designation would work instead of blue and yellow.

The default perspective theme uses variables (var(--neutral-90)), so a more elegant approach would be to set the variable instead of hardcoding the values.

2 Likes

This seems to work great. I just tested it.

However, it brings up a slightly different problem. Sometimes I need the rows to be a different shade of colors based off of the population for example. If the population is greater than 100,000 use these colors, otherwise use these other colors.

Is that possible in CSS?

It is possible, even preferred.
Conceptually you wouldshould add style names to the styles folder:
Capture

Then assign the style name to the element in your load script Instead of "light" and "dark" you would use one of the style names (e.g., "high-high", "high", "normal-range", "low", "low-low")
You can add multiple styles to an element and the last one wins.

If you want alternating high-high (high-high-light and high-high-dark) then perhaps a different way to use color might be considered. Implementing that will be tricky - you will be fighting the tools - and the result might not be as readable and usable as it could be.

2 Likes

Ok, I jumped around 20+ other forum threads and it still isn't clear to me what the solution is...

I have my "customYellow" overwriting the default styles for tables.

image

image

And I see how I could split that up into the odd/even rows but how do I apply a style based on the population value?

This is the part you do in a binding. It's possible to use an expression or other bindings plus script transforms.

Examine the population and return the appropriate style.

1 Like

Hmmm... the Table has properties for Striped with colors for even and odd - you don't need the entry in the stylesheet.css...
image

This is a really good find!

However, I am still unable to bind it to the individual population.

image

I am going to try to do this in a transform on the data itself.

It seems like you should be able to add a map transform, but you may need to do it in your load script. As this data isn't changing on Sort you will not have your original problem.

Something like

population = item["population"]

	if population > 1000000:
	    populationClass = "Test/Metropolis"
	elif population > 100000:
		populationClass = "Test/City"
	elif population > 10000:
		populationClass = "Test/Town"
	elif population > 1000: 
		populationClass = "Test/Village"
	else:
		populationClass = "Test/Community"

And then declare styles for all of those classes
image

I am not saying this is a good thing to do, but if you want to assign background color for the row based on population size as discussed above and still have alternation between even and odd rows you could adjust the brightness for even numbered rows in the stylesheet.css

.ia_table__body__row--even{
filter: brightness(150%)
}

1 Like

Hmmmmmmm, I haven't been able to make any method work so far. When you sort a table the data displayed seems to be different than the data in the data property.

I think I have to mark this as unresolved for now.

I thought about my original problem some more and I think I uncovered a bug with the sorting feature on a table or at least a discrepancy between how the table sorts things and how SQL sorts things.

Because to solve my problem I could sort by whatever criteria I wanted in the named query itself and then just color the rows as needed. It wouldn't necessarily matter if I sorted ASCENDING or DESCENDING.

image

So we can see the named query sorts alphabetically but the Ignition table sorts all capital letters first and then sorts all lower case letters.

So I think I have to turn off the table sorting ability and add some user friendly buttons to call a different query to sort how I want to sort things or setup my own coding to manipulate the dataset, color it, and then display it.

1 Like