Count background color in a power table

I have a script that turns the background “green” of a row based off another column value for that same row. Is there a way to count the how many rows in the same column are green?

How is your table’s data generated, what is your color script doing, and where do you want the count to be ?
And, more importantly, why ?

Table data was entered manually for roof fan tracking except one column uses a cell update binding which reads amps from different tags. I have three columns Running , Reduced, and Off. The script reads the amps in each row and in the running column it changes that rows background color to green. Yellow for Reduced and Red for Off. I have a numeric label I want to put the total count of for each one in.

from java.awt import Font
	
	data = self.data		
	returnValue = {}	
	
	
	
	if (colName == '% of FLA'):
		col1 = self.data.getValueAt(rowIndex, "FLA")
		col2 = self.data.getValueAt(rowIndex, "Amps")
		if col2:
			col3 = int(100*(col2/col1))
			return {'text': col3}

	
	if colName == "Running": 
			col1 = self.data.getValueAt(rowIndex, "FLA")
			col2 = self.data.getValueAt(rowIndex, "Amps")
			if col2:
				col3 = int(100*(col2/col1))
				if col3>=50:
					if data.getValueAt(rowIndex,"Amps" )> .2:
						returnValue["background"] = "Green"	
						#returnValue["text"]= 1
	
	if colName =='Reduced':	
		col1 = self.data.getValueAt(rowIndex, "FLA")
		col2 = self.data.getValueAt(rowIndex, "Amps")
		if col2:
			col3 = int(100*(col2/col1))
			if col3<50:
				returnValue["background"] = "Yellow"
				#returnValue["text"]= 1
	
	if colName =="Off":		
			if data.getValueAt(rowIndex,"Amps" )== 0:
				returnValue["background"] = "Red"
				#returnValue["text"]= 1
	return returnValue

Here is what the screen looks like

When and where is that script run ?

in the power table configureCell Extension Function

Don’t do this of the configureCell script. It gets called repeatedly whenever the table gets redrawn, and might not be called for all cells if some are hidden. It must only affect display, not data.

Process your data separately to produce this answer, applying the same logic as for display. You might find my view() expression function’s filtering and grouping capabilities helpful.

I read the total number of rows using a custom property on the table with a expression. How would I read the color count the same way?

I’m not sure I can help with finding a solution as I don’t use vision, but I thought I might contribute some code refactoring:

from java.awt import Font
	
hp = self.data.getValueAt(rowIndex, "FLA")
amps = self.data.getValueAt(rowIndex, "Amps")
if amps:
	ratio = int(100*(amps/hp))

if colName == "% of FLA":
	ret = {'text': ratio}
elif colName == "Running":
	if ratio >= 50 and amps > .2:
		ret = {'background': "Green"}
elif colName == "Reduced":
	if ratio < 50:
		ret = {'background': "Yellow"}
elif colName == "Off":
	if amps == 0:
		ret = {'background': "red"}
return ret

You can't. The color isn't stored anywhere. It is regenerated on demand by calling configureCell.

ok, so if I want to turn the background green and put a one in the column. Then can I count the ones?

Yes, that’s one approach, but not in configureCell. Take your color decision out of configureCell and put it in a propertyChange script (or view() expression) to produce a dataset with the color boolean per row of data. Count the true values while generating the data. Write the dataset and the count to custom properties. Then the configureCell function just has to check the boolean in the custom property for the requested row.

If you share your current code, we might be more helpful.

here is what I have currently

That’s the better way in my mind as well.

If you use a binding on table.data, create a custom property of type DataSet on your table on which you’ll recreate your existing binding, then on event.propertyName == ‘custProp’, add your additional columns (eg. Running) and set your modified dataset to table.data.

# propertyChange event on table
# Will write to custom Dataset property 'GreenDS' and
# custom integer property 'NumGreen'.

if event.propertyName == 'data':
  pyds = system.dataset.toPyDataSet(event.newValue)
  greens = []
  count = 0
  for row in pyds:
    green = row['Amps'] and row['Amps']/row['FLA'] >= 0.5 and row['Amps'] > 0.2
    if green:
      count += 1
    greens.append([green])
  event.source.GreenDS = system.dataset.toDataSet(['Green'], greens)
  event.source.NumGreen = count
# Snippet of updated configureCell

	if colName == "Running":
		if self.GreenDS.getValueAt(rowIndex, 0):
			returnValue["background"] = "Green"

My take is a bit different, in that I’d use a dictionary to help count all the statuses and then write it to a dataset. A lookup expression can extract the number you want.

if event.propertyName == 'data':

	dataIn = system.dataset.toPyDataSet(event.newValue)
	GYRheaders = ['green', 'yellow', 'red', 'unknown']

	#Initialize counters
	GYRCounters = {header: 0 for header in GYRheaders}
	
	for row in dataIn:
		if row['Amps']:
			load =  int(100 * row['Amps'] / row['FLA'])

			if load >= 50:
				GYRDict['green'] += 1

			elif .2 < load < 50:
				GYRDict['yellow'] += 1

			else:
				GYRDict['red'] += 1

		else:
			GYRDict['unknown'] += 1
	
	dataOut = [[GYRDict(color) for color in GYRheaders]]
	
	event.source.GYRDatasetProp = system.dataset.toDataSet(headers, dataOut)