Building the submenu is a little confusing but the actual logic to get stuff to the window instance is pretty simple. The other chunk of scripting is to take the passed tagPaths and build the proper chart configuration dataset from them.
Context Menu Script
from functools import partial
def addToTrend(event, selectedDataItem, window):
""" Add selected data item to existing trend window """
# Grab the existing list of trend items from the window root container:
trendDataItems = window.rootContainer.trendItems
# Add the selected data item's path/id to the dataset
newTrendItems = system.dataset.addRow(trendDataItems, row=[selectedDataItem])
# Put the new dataset back into the params for the window
window.rootContainer.trendItems = newTrendItems
return
def openTrend(event, number, selectedDataItem):
""" Open selected data item in a new trend window """
# Create a new dataset with the selected data item path
newTrendItems = system.dataset.toDataSet(['tagPath'], [[selectedDataItem]])
# Open a new instance of the trend window
system.nav.centerWindow(
system.nav.openWindowInstance("Path/To/Popup/Trend", {"trendId": number, "trendItems": newTrendItems}))
return
def buildAnalogValueContextMenu(event):
""" """
mainMenu, mainItems = [],[]
subMenuA, subMenuB, windowIds = [], [], []
# Get a list of all opened trend windows
openWindows = system.gui.findWindow("Path/To/Popup/Trend")
# Grab the tag path or some other id of the data we want to trend
selectedDataItem = event.source.tagPath
for window in openWindows:
if window.path == "Path/To/Popup/Trend":
# Grab the popup window number from the window's parameters
popupWindowNumber = window.rootContainer.trendId
# Add window id number to list so we can avoid collisions
windowIds.append(popupWindowNumber)
#Create sub menus
subMenuA = subMenuA + ["Trend %d" % popupWindowNumber]
subMenuB = subMenuB + [partial(addToTrend, number=trendId, window=window, selectedDataItem=selectedDataItem)]
if len(windowIds) > 0:
# Lazy collision avoidance, take largest number in the list and add 1
newTrendWindowId = max(windowIds) + 1
else:
newTrendWindowId = 1
# Add option to create new trend popup
subMenuA = subMenuA + ["New Trend"]
subMenuB = subMenuB + [partial(openTrend, number=newTrendWindowId, selectedDataItem=selectedDataItem)]
# Pack menu and display popup menu
subMenu = [subMenuA, subMenuB]
mainMenu += ["Create Trend"]
mainItems += [subMenu]
return system.gui.createPopupMenu(mainMenu, mainItems)
Using the above project library functions I then made a template that is just the analog value display, that takes the tag path for the analog display.
On the template 'mouseClicked' handler I put:
if event.button == event.BUTTON3:
newMenu = path.to.project.library.package.buildAnalogDisplayContextMenu(event)
newMenu.show(event, event.x, event.y)
I have pturmel's Integration Toolkit installed so I'm able to make the required trend dataset using the following expression:
Trend Dataset Expression
unionAll(
asMap(
"NAME", "str",
"TAG_PATH", "str",
"AGGREGATION_MODE","str",
"AXIS","str",
"SUBPLOT", "I",
"ENABLED", "B",
"COLOR", "clr",
"DASH_PATTERN", "str",
"RENDER_STYLE", "I",
"LINE_WEIGHT", "F",
"SHAPE", "I",
"FILL_SHAPE", "B",
"LABELS", "B",
"GROUP_NAME", "str",
"DIGITAL", "B",
"OVERRIDE_AUTOCOLOR", "B",
"HIDDEN", "B",
"USER_SELECTABLE", "B",
"SORT_ORDER", "I",
"USER_REMOVABLE", "B"
),
if(
len({Root Container.trendItems}) > 0,
forEach(
{Root Container.trendItems},
asMap(
"NAME", split(it()['tagPath'], "/")[len(split(it()['tagPath'], "/"))-1, 0],
"TAG_PATH", "[ProviderName]" + if(
len(split(it()['tagPath'], "]")) > 1,
lower(split(it()['tagPath'], "]")[1,0]),
it()['tagPath']
) + "/pv",
"AGGREGATION_MODE", "MinMax",
"AXIS", "Default Axis",
"SUBPLOT", 1,
"ENABLED", True,
"COLOR", color(175, 255, 25),
"DASH_PATTERN", "",
"RENDER_STYLE", 1,
"LINE_WEIGHT", 1.0,
"SHAPE", 0,
"FILL_SHAPE", True,
"LABELS", False,
"GROUP_NAME", "",
"DIGITAL", False,
"OVERRIDE_AUTOCOLOR", False,
"HIDDEN", False,
"USER_SELECTABLE", True,
"SORT_ORDER", None,
"USER_REMOVABLE", False
)
), asList()
)
)
Otherwise, you'll need to make an additional project library function to take the single column dataset trendItems
from the trend popup root container and transform it into the required dataset for the trend chart.
The required properties on the trend popup for my script to work are windowId
of string type, trendItems
of dataset type, and trendId
of integer type.
Edit:Found it Passing New Parameters to an Existing Popup Window - Vision.