# Get Chart (not Easy Chart) mode in script

**URL:** <https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662>\
**Category:** Ignition\
**Created:** [June 15, 2020, 4:25pm UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662 "2020-06-15T16:25:27Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![theerthraj.munusamy](https://avatars.discourse-cdn.com/v4/letter/t/45deac/32.png) [@theerthraj.munusamy](https://forum.inductiveautomation.com/u/theerthraj.munusamy)\
**Post date:** [June 15, 2020, 4:25pm UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/1 "2020-06-15T16:25:27Z")

</div>

Hi,

How can I get the chart (not easy chart) mode using script? I want to know if the chart is in X trace, Zoom, Pan or Mark mode.

Also I don’t see ‘propertychange’ invoked when the user changes mode. Is there a way to capture it!

Thank,  
Raj

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 16, 2020, 12:37am UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/2 "2020-06-16T00:37:58Z")

</div>

No.

It _ **is** _ readable in my [NoteChart module](https://inductiveautomation.com/moduleshowcase/module/automation-professionals-llc-notechart), which offers additional features on top of both the Classic Chart and the EasyChart components.

---

<div class="post-metadata">

**Author:** ![theerthraj.munusamy](https://avatars.discourse-cdn.com/v4/letter/t/45deac/32.png) [@theerthraj.munusamy](https://forum.inductiveautomation.com/u/theerthraj.munusamy)\
**Post date:** [June 16, 2020, 11:08am UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/3 "2020-06-16T11:08:00Z")

</div>

Thank you @pturmel. I will go over the documentation and get back.

---

<div class="post-metadata">

**Author:** ![klpe](https://avatars.discourse-cdn.com/v4/letter/k/59ef9b/32.png) [@klpe](https://forum.inductiveautomation.com/u/klpe)\
**Post date:** [October 7, 2022, 7:40am UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/4 "2022-10-07T07:40:06Z")

</div>

I'm on Ignition 8.1 and I have the exact same needs, any news on capturering the mode change?  
I have been experimenting with mouseReleased event and the poupTrigger, but cannot find a way to hook into the popupmenu to get the selected mode.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 7, 2022, 12:31pm UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/5 "2022-10-07T12:31:58Z")

</div>

The component stores this in a private field. You can use reflection to get it. In NoteChart, I simply overrode all the methods that affected it and used my own field.

If Reflection bothers you, note the solution above.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [October 8, 2022, 4:57am UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/6 "2022-10-08T04:57:50Z")

</div>

> [@pturmel](#):
>
> You can use reflection to get it

@pturmel's suggestion works, but it's clunky. I tested it from the mouseClicked, mousePressed, and mouseReleased events, and in all cases the event doesn't fire when the mode changes. This is probably because the radio buttons for changing modes are layered in a separate popup above the chart. It takes a second mouse click on the chart itself to trigger the event which is almost certainly undesirable. [The above solution](https://www.automation-pros.com/notechart/doc/index.html) makes more sense.

---

<div class="post-metadata">

**Author:** ![klpe](https://avatars.discourse-cdn.com/v4/letter/k/59ef9b/32.png) [@klpe](https://forum.inductiveautomation.com/u/klpe)\
**Post date:** [October 10, 2022, 11:00am UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/7 "2022-10-10T11:00:34Z")

</div>

I took a look at JFree chart docs and found that the popup get's called from the JFreeChartPanel so far so good. I also found your helper function [findJFChart(src)](https://forum.inductiveautomation.com/t/easy-chart-accessing-the-datasets-being-rendered/8709/9) which returns the parent JFreeChartPanel and the targeted JFreeChart but I'm not sure where to go from here.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [October 10, 2022, 11:42am UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/8 "2022-10-10T11:42:30Z")

</div>

@klpe Are you still trying to make this work from the classic chart, or have you switched to the module?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 10, 2022, 11:49am UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/9 "2022-10-10T11:49:28Z")

</div>

It isn't a field in JFreeChart--it is in IA's ChartPanel subclass (Classic Chart) and wrapper (EasyChart).

---

<div class="post-metadata">

**Author:** ![klpe](https://avatars.discourse-cdn.com/v4/letter/k/59ef9b/32.png) [@klpe](https://forum.inductiveautomation.com/u/klpe)\
**Post date:** [October 10, 2022, 12:06pm UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/10 "2022-10-10T12:06:05Z")

</div>

Thanks, I missed the fact that the ChartPanel was a wrapper to the EasyChart. I'll see where that takes me.

---

<div class="post-metadata">

**Author:** ![klpe](https://avatars.discourse-cdn.com/v4/letter/k/59ef9b/32.png) [@klpe](https://forum.inductiveautomation.com/u/klpe)\
**Post date:** [October 10, 2022, 12:38pm UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/11 "2022-10-10T12:38:23Z")

</div>

I put the code below in mouseReleased and now I can detect if zoom is selected. The timing is off, I check before the popup is opened, and I need to loop over the rest of the radiobuttons, but I think I'm on the right track.

```auto
from org.jfree.chart import ChartPanel, JFreeChart
from org.jfree.chart.plot import Plot

def findJFChart(src):
	"""IA's EasyChart and XYPlot components have their JFreeChart objects at different positions 
	in the Container/Component hierarchy. This helper function scans the hierarchy, given a container or 
	component as a starting point, and returns a tuple containing the parent JFreeChartPanel and 
	the targeted JFreeChart. Note: The hierarchy is searched depth-first! """  
	#from app.scriptmodule import findJFChart 
	try: 
		return (src, src.chart) 
	except: pass 
	try: 
		for x in range(src.componentCount): 
			try: return findJFChart(src.getComponent(x)) 
			except: pass 
	except: pass 
	raise ValueError, "Unable to Find a JFreeChart Instance"

if event.popupTrigger == 1:
	print "Popup triggered!"
	chart = event.source #parent.getComponent("Easy Chart")
	ch = findJFChart(chart)
	print(str(ch[0].getPopupMenu().getSubElements()[0].getComponent().getItem(0).isSelected()))
	

```

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [October 10, 2022, 7:31pm UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/12 "2022-10-10T19:31:47Z")

</div>

Add the following to the `configureChart` extension function:

```python
from java.awt.event import ActionListener
class CustomModeItemActionListener(ActionListener):
	def __init__ (self,comp):
		self.__comp = comp
	def actionPerformed(self,event):
		if event.source.isSelected():
			self.__comp.mode = event.source.text
	
pMenu = self.getPopupMenu()
	
for menuElement in pMenu.getSubElements():
	if menuElement.getLabel() == 'Mode':
		modeMenu = menuElement.getSubElements()[0]
		
		for item in modeMenu.getSubElements():
			for lis in item.getActionListeners():
				if 'CustomModeItemActionListener' in str(lis. __class__ ):
					item.removeActionListener(lis)
			item.addActionListener(CustomModeItemActionListener())

```

Here I have added a custom property to the root container (since that is the parent container of the chart). This script will add an Action listener to each of the items in the Mode Menu, when a new mode is selected it will change the value of the mode property to the selected mode.

It should go without saying to be careful with this, you'll notice that I am removing any actionListeners that we may have added to the items previously. This prevents a memory leak from not managing the life cycle of the listener. It also prevents having multiple listeners resulting in multiple action events.

Also, note that typically you would use `isinstance()` to check if an object is a certain type, but for whatever reason, I couldn't get `isinstance()` to work. I'm sure I'm missing something obvious there, but haven't figured out what.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [October 11, 2022, 5:56am UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/13 "2022-10-11T05:56:51Z")

</div>

Since the title of this thread says "(not Easy Chart)" I played around with this some more under the impression that we were working with the regular chart, but I see now that we've switched topics to the Easy Chart.

In any case, **working with the Basic Chart,** I originally went with Phil's suggestion and simply used reflection to get at the radio button positions. Since my original post, I discovered that it works quite well from the _ **mouseEntered** _ event handler, since it fires the moment the popup menu closes after a selection has been made.

Here is the code I used:

```auto
checkPan = event.source.getClass().getSuperclass().getDeclaredField("panItem")
checkPan.setAccessible(True)
isPanned = checkPan.get(event.source).isSelected()
checkXtrace = event.source.getClass().getSuperclass().getDeclaredField("xtraceItem")
checkXtrace.setAccessible(True)
isXtraced = checkXtrace.get(event.source).isSelected()
isZoomed = event.source.isDomainZoomable()
if isPanned:
	print "Pan Mode"
elif isZoomed:
	print "Zoom Mode"
elif isXtraced:
	print "XTrace Mode"
else:
	print "Mark Mode"

```

However, after reading @klpe's post, I realized that my code was MUCH more complicated than it needed to be. I went back and applied his approach to **the Classic Chart problem** , and I was able to return the same result with only 3 lines of code:

```auto
isPanned = event.source.getPopupMenu().getSubElements()[0].getComponent().getItem(1).isSelected()
isXtraced = event.source.getPopupMenu().getSubElements()[0].getComponent().getItem(3).isSelected()
isZoomed = event.source.isDomainZoomable()
if isPanned:
	print "Pan Mode"
elif isZoomed:
	print "Zoom Mode"
elif isXtraced:
	print "XTrace Mode"
else:
	print "Mark Mode"

```

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [October 11, 2022, 5:57am UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/14 "2022-10-11T05:57:04Z")

</div>

**For the Easy Chart** , I tested [@pturmel's approach](https://forum.inductiveautomation.com/t/easy-chart-accessing-the-datasets-being-rendered/8709/9) combined with [@klpe's method](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/11) for getting the radio buttons, and it works perfectly. However, if work is to be done with the code, there is no need to do the work every time the mouse enters the chart or every time the mouse enters some component on the chart, so rather than develop listeners, I simply added a custom component to the chart's parent container called oldMode. I then use the mode to evaluate whether or not work needs to be done at the _ **mouseEntered** _ event. Here is the code:

```auto
oldMode = event.source.parent.oldMode
def findJFChart(src):
	try: 
		return (src, src.chart) 
	except: pass 
	try: 
		for x in range(src.componentCount): 
			try:return findJFChart(src.getComponent(x)) 
			except: pass 
	except: pass 
	raise ValueError, "Unable to Find a JFreeChart Instance"
chart = event.source
ch = findJFChart(chart)
isPanned = ch[0].getPopupMenu().getSubElements()[0].getComponent().getItem(1).isSelected()
isZoomed = ch[0].getPopupMenu().getSubElements()[0].getComponent().getItem(0).isSelected()
isXtraced = ch[0].getPopupMenu().getSubElements()[0].getComponent().getItem(3).isSelected()
if isPanned:
	newMode = "Pan Mode"
elif isZoomed:
	newMode = "Zoom Mode"
elif isXtraced:
	newMode = "XTrace Mode"
else:
	newMode = "Mark Mode"
if newMode != oldMode:
	print newMode 
	#do work HERE
	event.source.parent.oldMode = newMode

```

---

<div class="post-metadata">

**Author:** ![klpe](https://avatars.discourse-cdn.com/v4/letter/k/59ef9b/32.png) [@klpe](https://forum.inductiveautomation.com/u/klpe)\
**Post date:** [October 11, 2022, 8:56am UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/15 "2022-10-11T08:56:01Z")

</div>

I ended up using Justins solution on my Easy Chart and it works perfektly 😃  
I think I misread the title of this post (not Easy Chart) as in not easy to work with.

I modified the code a little by removing the check with newMode != oldMode.  
I don't think it is that many updates in the mouse enter, not for my need's anyway.

On every mouseEnter I reset the background color of my mode buttons and change the color of the active button. Now when I change the mode in the popup Menu the color of the active button changes, simple I wouldn't have thought of that by my self.  
An image of my Easy Chart

 ![ChartMode](https://us1.discourse-cdn.com/inductiveautomation/original/3X/0/4/04e9e6ef7de389dbc5e5050cc04551ec1c77e3db.png)

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [October 11, 2022, 12:42pm UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/16 "2022-10-11T12:42:41Z")

</div>

> [@justinedwards.jle](#):
>
> there is no need to do the work every time the mouse enters the chart or every time the mouse enters some component on the chart, so rather than develop listeners, I simply added a custom component to the chart's parent container called oldMode

For posterities sake, (and because I too missed that we were talking about an EasyChart), my code which does add listeners to the popup menu, will work nearly as is with an Easy Chart, you just have to get the chart panel object.

> [@klpe](#):
>
> On every mouseEnter I reset the background color of my mode buttons and change the color of the active button.

With this code you will know the mode has changed when the mode actually changes.

Code should be placed in the configureChart extension function:

```python
	from java.awt.event import ActionListener
	class CustomModeActionListener(ActionListener):
		def __init__ (self,comp):
			self.__comp = comp
		def actionPerformed(self,event):
			if event.source.isSelected():
				self.__comp.mode = event.source.text
	
	def getChart(comp):
		if 'PMIEasyChart$EasyChart' in str(comp. __class__ ):
			return comp
		for c in comp.getComponents():
			return getChart(c)
		raise ValueError, 'Unable to find Easy Chart component'
		
	pMenu = getChart(self).getPopupMenu()
	
	for menuElement in pMenu.getSubElements():
		if menuElement.getLabel() == 'Mode':
			modeMenu = menuElement.getSubElements()[0]
			
			for item in modeMenu.getSubElements():
				for lis in item.getActionListeners():
					if 'CustomModeActionListener' in str(lis. __class__ ):
						item.removeActionListener(lis)
				item.addActionListener(CustomModeActionListener(self.parent))

```

As an aside, I am becoming convinced that there is a bug in Jython's implementation of `isinstance()` because I just can't get it to work, when it should work.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [October 11, 2022, 3:53pm UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/17 "2022-10-11T15:53:30Z")

</div>

@lrose  
Your code works quite well. To test it, I added the necessary custom property to my Easy Chart's parent container named `mode`, and I set up a button named Pan Mode with an expression binding to control its color:`If({Root Container.mode}="Pan",'java.awt.Color(0,250,0)','java.awt.Color(150,150,150)')`

At first, it wasn't working because, for unknown reasons, the configureChart extension function wasn't being triggered, but after I bound the background color of the chart to the background color of the parent container, the extension began firing and worked as described:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/2/82459b7c2226e1a6814aa6aca5a48589c6339a49.png)  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/4/5/4536c3141f71066cbd2bb9a815d311da23f64b09.png)  
When Pan Mode is selected, the button turns green, and when some other mode is selected, it turns grey

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [October 11, 2022, 11:52pm UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/18 "2022-10-11T23:52:27Z")

</div>

The only gotcha here is, if someone comes along and unknowingly throughs the chart in a group it will break as it will have a new parent.

Providing a path to the property might be a better option but I haven’t quite wrapped my head around that.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [October 11, 2022, 11:59pm UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/19 "2022-10-11T23:59:58Z")

</div>

It would be nice if we could put the custom properties directly on the chart.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 12, 2022, 12:05am UTC](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662/20 "2022-10-12T00:05:47Z")

</div>

The classic chart has always had that limitation as it uses the custom property infrastructure to supply its datasets.

[Next page](https://forum.inductiveautomation.com/t/get-chart-not-easy-chart-mode-in-script/35662.md?page=2)
