When you say âwhen invoked onceâ, where are you invoking getItemPaint?
I would expect that this method (from the AbstractRenderer base) is called whenever the chart wants to know what paint to use to colour a chart item, and hence it will be called for each item, prior to the chart drawing that item.
Is it an issue that it is being called in such a manner?
I have a button. When I click on it, it refreshes the dataset and runs the above code. If I say, give a print statement inside that method, it keeps printing it all the time. Even after the chart is refreshed and completely loaded.
Java Swing (and thus, JFreeChart) will call paint() methods continuously as it draws other things. For this and other reasons, they should thus be extremely optimized. Your configureChart method (assuming thatâs where youâre defining this) should only be called by Ignition when necessary to re-run your customizations, but getItemPaint will absolutely be called constantly, and thereâs nothing you can do about that.
Use code similar to what @jpark posted and add a column to your dataset to use as a flag. When you need to refresh the item which is being modified just set the proper flag in the dataset and your custom renderer will just take care of the rest.
All you need do is have the script check the flag column for each data point.
Note: This will allow multiple points to be formatted so if you only want 1 point to be changed you will need to insure that what ever method modifies the dataset does so correctly.
Hi @lrose, itâs a bit confusing for me to understand. If I add a another column, wouldnât that be another series? Also if I check that flag inside the method, the program would still execute the getItemPaint() right! Is there no way to stop this execution!
Yes, it would be another series, however, because you are providing the renderer you can control this.
There is no way to stop the execution, so you have to write the code in a way that this is not in play. Create the renderer class in the configureChart Extension function and then let the chart code call the renderer when it needs to.
Add a Column of type Integer or Short (the chart will argue with you if you use another type such as boolean.)
Then place this code in your configureChart extension function. This code has been tested and does work in vision 7.9
from java.awt import Color
from org.jfree.chart.renderer.xy import XYLineAndShapeRenderer
from java.awt.geom import Rectangle2D
#grabs a reference to plot of the chart
plot = chart.getPlot()
class MyRenderer(XYLineAndShapeRenderer):
def getItemPaint(self,series,row):
if series == 0 and plot.getDataset(0).getYValue(1, row) > 0:
return Color.RED
elif series == 0:
return Color.BLUE
#create an instance of your renderer
renderer = MyRenderer()
#Force the colorFlag not to render
renderer.setSeriesShapesVisible(1,False)
renderer.setSeriesLinesVisible(1,False)
#These lines modify the rendering of the data series
renderer.setSeriesLinesVisible(0,False)
renderer.setSeriesShape(0, Rectangle2D.Double(-3, -3, 6, 6))
#set the renderer of the plot to your custom renderer
plot.setRenderer(renderer)
Just a few modifications from what @jpark posted above, I added some comments to help explain what is happening. Notice that we are setting the lines and shapes of series 1 to not be visible, this keeps your added column from rendering to the chart.
In the getItemPaint we check the value of series 1 value for the given row, if it is greater than 0 then we choose a different color. If you remove the âelifâ segment of the code then default color will be used for the series. Any row which has a positive non-zero value will paint with the modified color. This is why if you only ever want 1 point to have the modified color you need to insure that only 1 row has a positive non-zero number.
@lrose I very much like the way you explain it. Thank you for that
I think I didnât explain the issue clearly. I am able to compare the Y Value with a parameter (ucl) like below and the code works.
if series == 0 and plot.getDataset(0).getYValue(series, row) > ucl:
The issue is that getItemPaint is called constantly and it slows down the window. I was looking for a way to stop this or at least not to slow down the page.
Thanks for explaining @lrose, I now get what you and @PGriffith saying. In regards to ucl and plot0 I use something like this. I dont have the exact script with me now.