How to learn perspective the right way?

For Perspective clients though, you also probably want to let the user know the thing didn’t work. For that I wrap my whole script content in try except blocks, with the except block calling a library script function that opens an error popup showing a custom message along with the traceback.format_exc()

7 Likes

Could you give a example

try:
   Stuff
except:
   shared.perspective.errors.displayError("Someone wrote the code bad, like this English")
#shared.perspective.errors
def displayError(msg=''):
   import traceback
   if msg != '':
      msg = "{}\r\n{}".format(msg, traceback.format_exc())
   else:
      msg = traceback.format_exc()
  
   system.perspective.openPopup('popup', 'popup', {'msg' : msg})

Sometimes you might want to check for Java errors as well, as these aren’t caught by the basic except. Especially if you have queries in your code.

from java.lang import Throwable

try:
  ...
except Throwable:
  ...
except:
  ...
4 Likes

Thank you

xD lets create a game in perspective to learn how to use perspective

not me tho, i would do way to much unorthodox css or js injections... i would be bad example for a starter xP maybe for the extra bonus levels

1 Like

What is the value of using a transform on a dataset from a named query? I can change the column names in the table props, change the order, sorting, hide, etc. I'm reading kgamble's essay and I'm not sure what value could be added to the data from a transform.

If someone could provide a couple of examples perhaps?

thanks,
mike

All sorts of benefits. For me it would include these:

  1. Write simple, readable and maintainable SQL queries and do the recordset manipulation in Jython scripting where the syntax is much more readable.
  2. Do data manipulation to provide CSS styles for cells depending on their value, etc.
  3. For views where multiple components may require some of the data I would bind a custom property to the named query and then do a script transform on that custom property for each component. For example, I might have production records that need to feed a table, a chart and a rate or OEE gauge. This way I only make one call to the database. All the manipulation is done in the script transforms.
  4. My production counters are stored in never-resetting format. Script transforms allow me to use the raw query data to create charts with count starting at zero, etc.

I would say only if you have to. WHERE, GROUP BY, HAVING and ORDER BY should get you pretty far with manipulating datasets and if you're doing any of these in jython (filtering, ordering, or group by-ing/pivoting) - I would put it in your NQ. Your database will do it much faster and more efficient than jython, and less stress on the ignition gateway server from not having to run a transform script.

2 Likes

I use custom props bound to a NQ regularly. Where a component needs a piece of that info, I use an expression transform. Any formatting is done via the component, at least for now. I don't have any components that require styling based on data values yet.

I agree! SQL is made for recordset manipulation.

As for CSS... I see a lot of people talking about CSS styling on the components, exactly HOW are you all doing it?

Work through the examples on the Table component.

https://docs.inductiveautomation.com/display/DOC81/Perspective+-+Table#PerspectiveTable-Examples

1 Like

That is a lot of coding to apply to a dataset. Do you find this affects performance at all on larger datasets?

Spend some time understanding and implementing project inheritance. It is very useful in developing a scalable and repeatable core set of styles, views, and script functions to use throughout your perspective projects. Lots of great threads about inheritance on these forums.

Regards,

Frank

You might want to use your named query binding on something else than tables, in which case you'll likely need to reprocess the output of the query to match the expected data structure.

1 Like

I would/do prefer an expression binding on a custom property on each component, and then a property binding to that custom prop. It’s more performant.

The exception would be if I am doing something that I do on several different components though out the project, in that case I write a script in a project library and use a transform to call that with a single line. Then the performance hit is worth the cost.

Raw Bindings > Transforms
Expressions > Scripts (transform or otherwise).

I also use and highly recommend @pturmels simulation aids module which makes dataset manipulations in a pure expression more accessible or possible at all depending on what you’re needing.

I do agree though that any manipulation that can be done in the database should be done there.

Since renamed, fyi:

2 Likes