Turn axes in Easy Chart on and off through scripting?

I was wondering if it’s possible in the Easy Chart component, to turn axes on and off through scripting. Our client wants to be able to display just one axis specific to a tag instead of having multiple axes.

E.g. say like you are charting 5 or 6 tags with different axes. You want to just display 1 axis for a tag, and click on a button to display the axis for that tag. The button has the label ‘Axis for Tag 1’ on it (subsequent buttons display “Axis for Tag 2”, “Axis for Tag 3”, etc). Is there a way in the button’s script to tell Easy Chart to make the ‘Axis for Tag 1’ visible, while making the others invisible? If this is possible can whichever axis that is selected be displayed in the same spot, preferably to the left of the chart?

All of the plots would remain on the chart, but just one axis would be displayed pertaining to the tag that is selected.

If this is not possible are there any other possibilities, besides multiple axes?

Thanks.

Well, the base Axis class in the JFreeChart library has a visible property, so it should be possible. Probably via configureChart().

I haven’t done it personally, but this might be helpful. setSeriesEnabled() might be worth playing around with as well, although it hides the entire line as well as the axis if it has no series.

stackoverflow.com/questions/3973 … ries-yaxis

In Ignition land it should look like this. Obviously chart should be a reference to your chart.-

plot = chart.getPlot()
range = plot.getRangeAxis()
range.setVisible(0)

Thanks Phil for your hint. It led me to the JFree class documentation:

http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/plot/XYPlot.html
http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/plot/Plot.html

My configureChart(self,chart) code example

plot = chart.getPlot()
plot.setDomainGridlinesVisible(False)
plot.setRangeGridlinesVisible(False)
plot.setOutlineVisible(False)

1 Like

Hi Phil,
Trying to make multiple Range Axes invisible on an EasyChart with a shared or combined Domain across several subplots. I might also need to manipulate the space the axes are taking up so as to give the chart more room.

I've isolated the "extraneous" Range Axes to the right side of each chart by manipulating the Axes.Data Position values.

Looking into this further I found that the the class the easyChart is a CombinedXYPlot (at least the way I have it configured) with a superclass of XYPlot. (if I have my terminology correct.) This is leading me to believe that I'll need to override a method of a super class to get at the axis visibility methods that are in the XYPlot class.

Any idea how to access getRangeAxisCount() method using jython syntax under the configureChart Extension Function?

I've tried extending the superclass with the subclass with an aim to use the "super" as indicated here, but Jython doesn't seem to play well with the way I'm implementing it as shown below:

p = chart.plot
CombinedRangeXYPlot extends XYPlot
ra = super.plot.getRangeAxis()
print p
print ra

Any ideas how to get at these the methods in the superclass?

#Edit:

I've tried getting the methods available if I do:

p = chart.getPlot
d = dir(p)

and get:

<bound method org.jfree.chart.JFreeChart.getPlot of org.jfree.chart.JFreeChart@100bf8c6>
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__',
 '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__',
 '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'im_class',
 'im_func', 'im_self']

but still don't see an angle to get at methods as documented in the XPPlot class.

Accessing the super class’ methods from the subclass is as simple as calling them:
chart.getPlot().getRangeAxisCount(); see the Javadocs for JFreeChart here:
http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/plot/CombinedRangeXYPlot.html

Hi Paul,
Tried accessing via the chaining method suggested a la:

ra = chart.getPlot.getRangeAxisCount()
d = dir(ra)
print ra
print d

but got the method exception below:

ERROR [EasyChart-AWT-EventQueue-2] Error invoking extension method.
Traceback (most recent call last):
  File "<extension-method configureChart>", line 12, in configureChart
AttributeError: 'instancemethod' object has no attribute 'getRangeAxisCount'

Is it a scope thing inside an extension function?

Okay, so I imported XYPlot from org.jfree.chart.plot w/o complaint, but still trying to wrestle with feeding the methods the args they need. Such picky eaters, those java methods.

Thanks for the nudge in the right direction. The battle continues at least.

AttributeError: 'instancemethod' object has no attribute 'getRangeAxisCount'

Right - you need to either use the JavaBeans get<prop>/set<prop> standard, in which case you must call the function: var = chart.getPlot().getRangeAxisCount()
or
use Jython's auto-magic wrapper around bean properties, with direct address:
var = chart.plot.rangeAxisCount

What you're doing there is going from the chart object to its getPlot function, then trying to call getRangeAxisCount() from the function, not the result of the function.

1 Like

Ah....I see. With the missing () for .getPlot, I'm only asking for the object, not the result of the function? (i.e. mixing my syntax, hence the reason for the error indicating the object has no attribute....) So now, with:

p = chart.getPlot()
rac = p.getRangeAxisCount()
d = dir(rac)
print p
print d
print rac

I get:

org.jfree.chart.plot.CombinedDomainXYPlot@194864f
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__',
 '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__getattribute__',
 '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__',
 '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', 
'__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__',
 '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', 
'__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__',
 '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__',
 '__rxor__', '__setattr__', '__str__', '__sub__', '__truediv__', '__xor__']
1

Now that I'm using the correct syntax, I'm surprised it only registers 1 range axis. Digging further...

Thanks for the syntax correction and awesome explanation!! Trying it in python wrapper out of curiosity, and for the practice. And voila. Magic indeed (assuming the case change only applies to the initial caps typically? --more reading to do)

The magic is provided by jython itself, inspired by Java NetBeans, like so:

  • Methods with the signature public SomeType getSomeName() are exposed as readable property someName. Like so:
    print someObject.someName
  • Methods with the signature public void setSomeName(SomeType val) make the above property writable. Like so:
    someObject.someName = newvalue
  • As a special case, methods with the signature public boolean isSomeName() are exposed as readable boolean property someName.
    print 'True' if someObject.someName else 'False'
1 Like

Thanks for providing this very helpful context generalizations/translation. I’m trying to apply it to this proposed solution on stackoverflow:

how-to-hide-jfreechart-xyseries-yaxis

After applying your Introspection module to chart.plot of the configureChart extension function, it became clear that the method setVisible() is not in chart.plot (which appears to me to be a CombinedDomainXYPlot object).

Unless I’m missing something (again), if I’m to access the setVisible method on the Axis subclass of org.jfree.chart.axis, which is on a different “fork” of the superclass org.jfree.chart I’ll need to figure out:

How do you use a method in one subclass and use it in a “sibling” subclass? More literally, in my case, I’m trying to apply the setVisible() method to a CombinedDomainXY object.

I get the feeling I’m being encumbered by trying to do this with the configureChart extension function.

Seems too complicated to be trivial, but I can’t be the first one to want to “invisible” several y-axes on an easychart…

Based on the docs for XYPlot, try something like this (note the check for a possible null ra):

xyplot = chart.plot
for rai in range(xyplot.rangeAxisCount):
	ra = xyplot.getRangeAxis(rai)
	if ra:
		ra.visible = False

Thx Phil.
Been doing a ‘deep’ dive on encryption lately…deep for me.

Getting back to this, I found I had to drill down into the subplots to access the “visible” method on the various axes of each plot. I’ve got 3 subplots on my EasyChart, and wanted to give the user the ability to turn Y-axes on/off with a checkbox.

I tested your code provided above, but it would not work on my “CombinedDomainXYPlot”. After swimming through several layers of javadocs, I pressed your Introspect library into service to more quickly take stock of objects at various levels of the JFreeChart library, and their current values if any. Invaluable to me. Thank you.

The following code was the result for those looking to get started with controlling the Y-axes on a multiple subplot easychart:

## This code works to make invisible all range(y-axes) for 
## each subplot on the basis of the value of a checkbox in the header when
## the this function is called.
	
cb2 = self.parent.getComponent('Supply_Demand Header')\
.getComponent('PenCntrlContainer')\
.getComponent('CheckBox 2').selected

ch = chart
p = ch.plot
pt = p.plotType
sp = p.subplots
spa = sp.get(0)
spb = sp.get(1)
spc = sp.get(2)
for ria in range(spa.rangeAxisCount):
    if ria >= 0:
        spra = spa.getRangeAxis(ria)
        if spra:
            spra.visible = cb2

for rib in range(spb.rangeAxisCount):
    if rib >= 0:
        sprb = spb.getRangeAxis(rib)
        if sprb:
            sprb.visible = cb2

for ric in range(spc.rangeAxisCount):
    if ric >=0:
        sprc = spc.getRangeAxis(ric)
        if sprc:
            sprc.visible = cb2

Now that I have this general On/Off functionality working, I’m now trying to use one of the event handlers on the checkbox to call the configureChart Extension function, or possibly just importing all the necessary libraries and this code into that event listener on the checkbox.

The other improvement I’m pursuing is to give the user the ability to pick and choose which y-axes are showing, but this would require figuring out how EasyChart assigns indices to axes, and working through the logic to pick out the ones they want, or sort by a particular dataset heading using system.dataset.sort, but I’m not sure is sorting the AXES dataset will actually change the assigned axis indices. This exercise should help solve the problem of moving a trace’s order or layer, such that one is in front of or behind another regardless of which order they were entered when building the chart from scratch.

My first test will involve simply sorting the AXES dataset to see if the assigned indices within the subplot objects have changed accordingly. Then I can alter the ria, rib, and ric logical test values to select the axes I want for each subplot.

It appears that the indices are fixed (likely set at creation time). Despite sorting the AXES dataset, the indices remain unchanged.