Dynamically Add Tag Pens to Easy Chart from parameters

I’m passing UDT tag info from a button to a popup. I would like to add a pen to an easy chart for each UDT tag passed in. I tried using cell updates but the number of tags being added isn’t always the same. I tried to accomplish this by scripting on the root component of the popup. For clarification I have successfully passed parameters to the popup, just haven’t been able to add pens dynamically. I am not getting any errors but it does not appear any pens are being added. This is the script I am using:

property change script:
data = event.source.getComponent(‘Easy Chart 1’).tagPens
pen1Tag = event.source.Pen1.Equip_ID
pen1Path = event.source.Pen1.PV
pen1Color = “000000”
pen2Tag = event.source.Pen2.Equip_ID
pen2Path = event.source.Pen2.PV
pen2Color = “000002”
event.source.createPen(pen1Tag, pen1Path, pen1Color, data)
event.source.createPen(pen2Tag, pen2Path, pen2Color, data)

custom method:
data = event.source.getComponent(‘Easy Chart 1’).tagPens
pen1Tag = event.source.Pen1.Equip_ID
pen1Path = event.source.Pen1.PV
pen1Color = “000000”
pen2Tag = event.source.Pen2.Equip_ID
pen2Path = event.source.Pen2.PV
pen2Color = “000002”
event.source.createPen(pen1Tag, pen1Path, pen1Color, data)
event.source.createPen(pen2Tag, pen2Path, pen2Color, data)

Still a little unclear about what you are doing here, I understand the idea, but the script you have provided doesn’t show the needed steps to add a tag to the Tag Pens dataset.

I assume that the createPen function you are calling is a custom function on the root container? But if you have shown that script it isn’t marked clearly as being that.

Also, note that in property change scripts of components you should always filter for the property change that you want to trigger the script. For instance if you are looking for a data property to change then the script should have a similar structure to this:

if event.propertyName == 'data':
     #do work here

This will prevent your script from executing at unexpected times.

All that really needs to be done to accomplish what you are looking for is to add a row to the tagPens data set. To do that successfully you need to supply all of the settings for each pen. The easiest way to get this information is to set up a tag pen on your easy chart and then copy all of the data values and substitute programmed values where needed to make it dynamic. Then you can use system.dataset.addRow to return a new tagPen dataset with the additional row.

data = event.source.getComponent('Easy Chart 1').tagPens
newRow = ['Insert all row data here']
event.source.getComponent('Easy Chart 1').tagPens = system.dataset.addRow(data,newRow)

Note that it is important that the tagPen dataset has all of the columns it is expecting.

The custom method script I pasted was incorrect (It was a copy of the property change script). Looks like I may just need to add the if event.propertyName script. The method script I’m using is:

def createPen(self, selectedTag, tagPath, color, data):

col1Name = selectedTag
col2Path = tagPath
col3Aggregation = "MinMax"
col4Axis = "Default Axis"
col5Subplot = "1"
col6Enabled = "true"
col7Color = color
col8Dash = ""
col9Render = "1"
col10Line = "1"
col11Shape = "0"
col12Fill = "true"
col13Labels = "false"
col14Group = ""
col15Digital = "false"
col16Override = "false"
col17Hidden = "false"
col18user_select = "false"
col19Sort_order = ""
col20User_Rem = "false"

data = system.dataset.addRow(data, [col1Name, col2Path, col3Aggregation, col4Axis, col5Subplot, col6Enabled, col7Color, col8Dash, col9Render, col10Line, col11Shape, col12Fill, col13Labels, col14Group, col15Digital, col16Override, col17Hidden, col18user_select, col19Sort_order, col20User_Rem])

I attempted to use the above script and method in a script on the window itself to have it update every time the window is opened but there are still no pens created.

The idea is to have a generic trend button on a bunch of different screens that each have their own custom properties with the data for the pens. When the button is pressed it passes the custom property pen data onto the trend popup. The script then dynamically adds the pens to the trend based on the passed parameters. This prevents having to create multiple trend screens or for the operator to have to select pens. It is all done based on the screens they are looking at.

In your property change script you create a variable called data and link it to tagPens then pass it to your custom method. I don’t see where your custom method writes it back to your easy chart or where its passed back to your property change script to be written back to your easy chart. Am I missing something?

Okay, so that does help, but you will need a little more than just the filter to make this work. You have to return data and set the tag pens property to the modified data set. I’m also going to suggest that you use a dictionary in your custom method to prevent needing to call the method more than once.

property change script:

if event.propertyName == 'yourProperty':
     data = event.source.getComponent(‘Easy Chart 1’).tagPens
     pen1Tag = event.source.Pen1.Equip_ID
     pen1Path = event.source.Pen1.PV
     pen1Color = “000000”
     pen2Tag = event.source.Pen2.Equip_ID
     pen2Path = event.source.Pen2.PV
     pen2Color = “000002”
     event.source.getComponent('Easy Chart 1').tagPens = event.source.createPen([{'tag':pen1Tag,'path':pen1Path,'color':pen1Color},{'tag':pen2Tag,'path':pen2Path,'color':pen2Color}], data)

Custom method:

def createPen(self, tags,data):
     for tag in tags:
          data = system.dataset.addRow(data,[tag['tag'],tag['path'],'MinMax','Default Axis',1,1,tag['color'],'',1,1,0,1,0,'',0,0,0,0,'',0])
     return data

Thank you for all the help. I have the script in a visionWindowOpened event handler and I’m not getting any errors but it is not populating any pens. Is this because this event is handled prior to any binding evaluations? Here is my script and custom method:

visionWindowOpened script:

data = system.gui.getParentWindow(event).getComponentForPath('Root Container.Easy Chart 1').tagPens
pen1Tag = system.gui.getParentWindow(event).getComponentForPath('Root Container').Pen1.Equip_ID
pen1Path = system.gui.getParentWindow(event).getComponentForPath('Root Container').Pen1.PV
pen1Color = "000000"
pen2Tag = system.gui.getParentWindow(event).getComponentForPath('Root Container').Pen2.Equip_ID	
pen2Path = system.gui.getParentWindow(event).getComponentForPath('Root Container').Pen2.PV
pen2Color = "000010"	
system.gui.getParentWindow(event).getComponentForPath('Root Container.Easy Chart 1').tagPens = event.source.createPen([{'tag':pen1Tag,'path':pen1Path,'color':pen1Color},{'tag':pen2Tag,'path':pen2Path,'color':pen2Color}], data)

custom method:

def createPen(self, tags, data):
	for tag in tags:
		data = system.dataset.addRow(data, [tag['tag'],tag['path'],'MinMax','Default Axis',1,1,tag['color'],'',1,1,0,1,0,'',0,0,0,0,'',0]) 
	return data

visionWindowOpened fires before bindings are evaluated so everything you have in the script that references a binding on the screen would not be able to complete. If you want it to fire everytime someone navigates to the screen then you could try using internalFrameActivated or do it as a propertyChange script on the easy chart with your if like:

if event.propertyName == 'componentRunning':

Also I could be wrong but I don’t believe you can do your get component that way. I believe you would need separate get components for the root container and for your easy chart. I would test it out using print statements as you build it and try having it print a value from the component your trying to reach to make sure you are seeing it. You would need to look in the diagnostic console to view your print statements since they are on a function that only works while loading.

1 Like