Bar chart (report) static line

I have a simple bar chart in a report I am using SQL to fill the chart. I need a “static” line at a certain value to use as a straight “max” line. I can draw a line, but as the scale of the chart changes dynamically, the line is no longer where it is supposed to be. Is there some code I could add to the chart to position the line appropriately? Or some other method?

Thanks

1 Like

Untested, but you would need something like this in the chart configuration script:

from org.jfree.chart.plot import ValueMarker
marker = ValueMarker(123) #point on range axis to label
marker.setLabel("Some Marker")
chart.getPlot().addRangeMarker(marker)
2 Likes

Thanks! Will give it a try!

That worked (of course)…my next question is are there other properties I can set for the marker, where can I learn about them? I only need line weight and color!

Thanks

The best reference is JFreeChart’s API/Javadoc; for instance, the ValueMarker class is defined here:
http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/plot/ValueMarker.html

Line weight and color can be set by using one of the overloaded constructors;

ValueMarker(double value, Paint paint, Stroke stroke)

Paint is a base Java class that’s implemented by Color, so you can just use system.gui.color(r, g, b).
Stroke is easiest to define with the BasicStroke class - so just import that class, and use a new instance in the call when you create a new ValueMarker instance.

Thanks again for your help!

1 Like

Is it possible to do similar coding to add a reference line to the Bar Chart object in the Vision Module?

Yes, similar code should work; I don’t know exactly what differences would be required offhand.

Using code I successfully used in a report’s bar chart, I set this script up in the Event Handler PropertyChange:

from java.awt import BasicStroke
from org.jfree.chart.plot import ValueMarker
goal = 0.5

s = BasicStroke(
4.0, #width
BasicStroke.CAP_ROUND, #cap
BasicStroke.JOIN_ROUND, #join
1.0)

m = ValueMarker(goal, system.gui.color(255, 10, 10), s)
chart = event.source.parent.getComponent(“Bar Chart”)
chart.getPlot().addRangeMarker(m)

When it runs, I get the error: AttributeError: ‘com.inductiveautomation.factorypmi.application.com’ object has no attribute ‘getPlot’

Add a getChart() after getComponent("Bar Chart") - getComponent gives you the Ignition component, from which you need to getChart() to get the underlying JFreeChart object.

I guess I don’t know the syntax for that:

chartIgn = event.source.parent.getComponent(“Bar Chart”)
chart = chartIgn.getchart()
chart.getPlot().addRangeMarker(m)

AttributeError: ‘com.inductiveautomation.factorypmi.application.com’ object has no attribute ‘getchart’

getChart(), not getchart() - has to match case.

Ugh - sorry. Yep, that works.

I ended up consolidating it to:
chart = event.source.parent.getComponent(“Bar Chart”).getChart()

Thanks!

1 Like

This is working well in my dashboards. On the reports, which is where I first got it working, the reference line shows up in the preview in the report module, but not in the PDF when the report is emailed. Everything else renders in the PDF as expected.

Any ideas what’s preventing the line from rendering in the PDF?

The code is:
from java.awt import BasicStroke
from org.jfree.chart.plot import ValueMarker
goal = 0.5

s = BasicStroke(
	4.0, #width
	BasicStroke.CAP_ROUND, #cap 
	BasicStroke.JOIN_ROUND, #join
	1.0) #, #miterLimit
	#[2, 4, 8, 16, 32], #dash pattern
	#0.0) #dash_phase_offset

m = ValueMarker(goal, system.gui.color(255, 10, 10), s)
#m.setLabel("Target Over")
chart.getPlot().addRangeMarker(m)

system.gui functions only exist in client/designer scope. Manually import java.awt.Color (or use a project script):

from java.awt import Color
red = Color(255, 10, 10)

Yep, that fixed it. Thanks again!

1 Like

I found the Marker Label is partially cutoff on the left bar. This is what I did to correct this.
RectangleInsets(top,left,bottom,right)

from org.jfree.ui import RectangleInsets
m.setLabelOffset(RectangleInsets(5,10,0,0))

Before:
image

After:
image

How can you get this to work on a Chart component that has sub plots?
I have managed to get it working when i only have one dataset, but i’ve got another component with two datasets on different plots.
I’d like to add a different marker to each plot. I’ve tried calling:
plot = event.source.getChart().getPlot()
But i suspect there needs to be a way to tell it which plot im interested in? Strangely i’m not getting any marker showing up, nor any errors.

If getPlot() returns a org.jfree.chart.plot.CombinedDomainXYPlot (you can import that class and check isinstance), then it will have a getSubplots() method that returns, naturally, the subplots, which is where you want to actually apply your markers.

Thanks, that worked a treat. I did try and look at the JFree chart docs before posting a question, but i don’t seem to be very good at navigating it. For instance i thought getPlot() returned “org.jfree.chart.plot”, and i was looking at those methods, which doesn’t have getSubplot().

Could you give me a hint of how you traced that out?