Customizing Perspective Table and json scripting help

Thanks

The asterisks are pretty new to me in Python.

1 Like

Look up packing and unpacking regarding python to understand the asteriks in python. Usually are used to unpack/pack dictionaries/lists/tuples. Very helpful shortcut when you get the hang of it.

Decent enough article on it Packing and Unpacking Arguments in Python - GeeksforGeeks

1 Like
baseStyle = {
			'fontSize': 36,
			'fontWeight': 500,
			'borderStyle': 'ridge' 
		}
subStyle= dict(backgroundColor= '#FF3131', **baseStyle)

This didn’t work.
I am not sure, but I think it is the format.

Formatting isn’t an issue (for me anyway).

1 Like

Was it the tick marks on green that made the difference?

subStyle= dict(backgroundColor= '#FF3131', **baseStyle)
This didn’t work. Does that mean it was the tick marks or is the return different than the variable being returned?

You’re not showing your actual code, but it’s different from anything I’ve posted, because I don’t have a subStyle variable. Without showing the actual full code, it’s impossible to determine what’s going wrong.

1 Like

Thanks for helping.
I will try it again on Monday.

Edit: I had a container set the wrong size, got my table to be smaller now.
After testing a bit though, , 'minHeight':600 did change the result.

Not sure how to implement the base style concept still.

def getStyle(row, col):
			baseStyle = {	'fontSize': 30,	'fontWeight': 500,	'borderStyle': 'ridge' , 'minHeight':30		}
			if 		value.getValueAt(row,"Running")==0 and value.getValueAt(row,"StateDuration")>=5  and value.getValueAt(row,"Infeed")>1000 and value.getValueAt(row,"Outfeed")>1000:
				subStyle= {'fontSize': 30,'fontWeight': 500,'backgroundColor': '#FF3131', 'borderStyle':'ridge', 'minHeight':30 }
			elif 	row%2==0 :
				subStyle= {'fontSize': 30,'fontWeight': 500,'backgroundColor': '#ffffff', 'borderStyle':'ridge', 'minHeight':30}
			elif  	row%2!=0  :
				subStyle= {'fontSize': 30,'fontWeight': 500,'backgroundColor': '#a0bed8', 'borderStyle':'ridge', 'minHeight':30}
		
							
			return subStyle

	value = [{value.getColumnName(col):{'value': value.getValueAt(row,col), 'style': getStyle(row, col) } for col in  range(value.getColumnCount())} for row in range(value.getRowCount())]

	return value	

You would implement it like this:

def getStyle(row, col):
	baseStyle = {'fontSize': 30,'fontWeight': 500,'borderStyle': 'ridge' ,'minHeight':30}
	if 	value.getValueAt(row,"Running")==0 and value.getValueAt(row,"StateDuration")>=5  and value.getValueAt(row,"Infeed")>1000 and value.getValueAt(row,"Outfeed")>1000:
		return dict(backgroundColor = '#FF3131', **baseStyle)
	elif row % 2:
		return dict(backgroundColor = '#ffffff', **baseStyle)
	else:
		return dict(backgroundColor = '#a0bed8', **baseStyle)


	value = [{value.getColumnName(col):{'value': value.getValueAt(row,col), 'style': getStyle(row, col) } for col in  range(value.getColumnCount())} for row in range(value.getRowCount())]

	return value

At the very least, don’t define baseStyle and then never use it, you could also do this:

def getStyle(row, col):
	baseStyle = {'fontSize': 30,'fontWeight': 500,'borderStyle': 'ridge' ,'minHeight':30}
	if 	value.getValueAt(row,"Running")==0 and value.getValueAt(row,"StateDuration")>=5  and value.getValueAt(row,"Infeed")>1000 and value.getValueAt(row,"Outfeed")>1000:
		baseStyle['backgroundColor'] = '#FF3131'
	elif row%2:
		baseStyle['backgroundColor'] = '#ffffff'
	else:
		baseStyle['backgroundColor'] = '#a0bed8'

	return baseStyle


	value = [{value.getColumnName(col):{'value': value.getValueAt(row,col), 'style': getStyle(row, col) } for col in  range(value.getColumnCount())} for row in range(value.getRowCount())]

	return value	
2 Likes

Thanks

I didn’t know it was possible to set new values and keys with :
dictionaryName[key]=value
If I understood that correctly.


I am struggling a bit trying to append a totals column.

Scrap='0.0%'
# Scrap=sum(value.getValueAt(row,value.getColumnIndex('Scrap') for row in range(value.getRowCount()))
Total= {'Line':{'value':'Total','style':baseStyle} , 
	    'Scrap':{'value':Scrap,'style':baseStyle} }
value.append(Total)

I got this to sort of work.
The commented out line though, it doesn’t work and I am not sure why.

This page uses double quote instead of single, is that right?
https://docs.inductiveautomation.com/display/DOC81/Datasets#Datasets-AccessingDatainaDataset

At first glance it looks alright, what error/unexpected result is it giving you?

Python is quote agnostic, it doesn't care if you use single or double quotes, so long as they match.

print "This string will 'allow' single qoutes because they are contianed by double quotes"
print 'This string will "allow" double qoutes because they are contined by single quotes'
print 'Though you can use \'escape\' characters if you really want to'
2 Likes

Thanks

I was calling dataset functions on the list I had created to return the json.
Fixed that.

Now I named that list value2, and I append to value2.
Also, I had too many parenthesis.

Two questions:

  1. Is there a way to change the value in the dataset with the if statements in that def style function?

  2. Can I change the border of a row without impacting the vertical lines between cells?


Thanks LRose!
Removed the non-sense code I had in this spot.


I think I can edit the colors of each side of a cell independently, but it looks messy to set the row border to highlight.

You're looking for system.dataset.setValue(), which because datasets are immutable (this is why there are not set* functions on the dataset object) returns a new dataset object with the value at the specified location set to the provided value.

3 Likes

Is it possible to make the table look like labels on a flat color?
No border, no cells, not look like a table at all?

I have 3 labels with separate bindings right now, and then three other labels as headers.
My thought is that if I can conceal that I am using a table, I can use a single binding on the component.


It will eliminate some bindings for me.
It will reduce some work for me.
It will eliminate this issue I have where if I bind to another object, and then property reference then when the page loads for a very small amount of time the page appears to have an error on load.

Worst case scenario you can hide everything with css...

edit:

Well, if you disable the header and pager, disable the stripes, add 'borderStyle: none' to the table styles...
Isn't that what you want ?

2 Likes

Meh, I would create a custom property and with you data binding, and then use an expression binding on each label to that with and expression binding using the lookup() expression.

Don't overcomplicate things for the sake of optimization.

2 Likes

Premature optimization is the root of all evil

1 Like

I don't think it is premature optimization.
The page has existed for a long time.
When do you think is a good time for optimization?

I mean try to use best practices when I initially design a page, but I have plenty of old projects I have to occasionally maintain or update that have plenty of non-ideal setups, but only when someone complains "hey this thing is really slow" will I try to optimize. However many of the non-ideal setups work well enough that I never hear that.

I would say its appropriate to optimize when 1) there is a noticeable performance issue that users notice and 2) you know that it's an issue with your design of the page and not something else (network latency, a slow db, etc). There is plenty to cause bad performance in a vision/perpective application before you ever look at the designer. Not to say bad design can't be the cause, god knows I've made accidental infinite property change loops that crashed my vision application before lol. But it's good to check all your bases and try to figure out what is the main cause of the slowness so your optimization can be pointed at the right thing. You could very well optimize this page and still have performance issues because that was not the problem for instance.

2 Likes