Show tooltipText in foreground of the Status Chart - Vision

Good morning,

I would like to show some data, for example the "timeDiff" as shown in the attachment. I can show what I need with the getTooltipText extension, but I would like to have it always in the foreground of every series.

Should be possible?

Thanks for the help

I don't see the attachment

Hi Justin, I forgot it :sweat_smile:

1 Like

Interesting problem. I imagine that you are going to have to add a StandardXYSeriesLabelGenerator to your plot renderer using the configureChart extension function.

1 Like

Ok, thanks for the suggestion!

1 Like

Were you ever able to get this working? I've experimented with several approaches to this problem, but so far, I've had no luck.

I finally developed a reliable way to achieve this result. Initially, I tried various label generators, but all I could get them to do is apply a single label to each series, so it appears that I was mistaken in my initial suggestion.

What ended up working quite well are XYTextAnnotations. Below is a script that iterates through the chart data, and calculates the appropriate place to put the annotations. Since timeDiff is what was requested in the original post, in the below example, I calculate it for each data block and apply it accordingly.

Here is the script:

from org.jfree.chart.annotations import XYTextAnnotation
from java.awt import Color
chartComponent = system.gui.getParentWindow(event).getComponentForPath('Root Container.Status Chart')
data = chartComponent.data
chart = chartComponent.chart
plot = chart.XYPlot
for annotation in plot.getAnnotations():
    if isinstance(annotation, XYTextAnnotation):
    	plot.removeAnnotation(annotation)
def generateLabel(series, item, lastItemIndex):
	x = series - 1
	startDate = data.getValueAt(lastItemIndex, 0).getTime()
	endDate = data.getValueAt(item, 0).getTime()
	y = (float(startDate) + float(endDate)) * 0.5
	timeDiff = str((float(endDate) - float(startDate)) / 1000) #Time diff is being calculated here, but this could be literally anything
	annotation = XYTextAnnotation(timeDiff, x, y) #Timediff string added to chart
	annotation.setPaint(Color.BLACK)
	annotation.setFont(chartComponent.rangeAxisFont)
	plot.addAnnotation(annotation)
for series in range(1, data.columnCount):
	lastItemValue = data.getValueAt(0, series)
	nextItemValue = data.getValueAt(1, series)
	lastItemIndex = 0
	for item in range(1, data.rowCount):
		if lastItemValue != nextItemValue:
			generateLabel(series, item, lastItemIndex)
			if (item + 1) < data.rowCount:
				lastItemValue = nextItemValue
				nextItemValue = data.getValueAt(item + 1, series)
				lastItemIndex = item
			else:
				generateLabel(series, item, lastItemIndex)
		else:
			if (item + 1) < data.rowCount:
				nextItemValue = data.getValueAt(item + 1, series)
			else:
				generateLabel(series, item, lastItemIndex)

Here is the result:

Here is the result zoomed:

The script automatically removes all old annotations before applying new ones, so it can be fired as much as needed. I would probably stick this into a custom method and trigger this once when the window opens, and then retrigger it any time the data changes off of a property change event script.

Edit: Getting the rangeAxis upper bound is not needed, and it was simply overlooked artifact from the development process. That logic has been removed from the above script

2 Likes

Looking at this, it looks a little silly to me displaying elapsed time in seconds over timespans that cover days or even weeks, so remembering a function I recently developed for summing timespans in power tables, I figured it could be easily applied to this as well. If the following function is added to the above script:

def format_time(timestamp):
	days = int(timestamp / 86400)
	hours = int((timestamp % 86400) / 3600)
	minutes = int((timestamp % 3600) / 60)
	seconds = int(timestamp % 60)
	output = []
	if days > 0:
		output.append(str(days) + 'd')
	if hours > 0:
		output.append(str(hours) + 'h')
	if minutes > 0:
		output.append(str(minutes) + 'm')
	if seconds > 0:
		output.append(str(seconds) + 's')
	return ' : '.join(output) if output else '0s'

and the timeDiff = line is changed from str((float(endDate) - float(startDate)) / 1000) to format_time((float(endDate) - float(startDate)) / 1000)

The result will look like this:

Edit: added missing return statement to function

1 Like

Hi Justin, I totally forget to answer, sorry.
I didn't find anything to make it work so I abandon the chart for the moment; thank you very much for your help, the script is crazy and the result is exactly what I need.

In the next days I will make some test on the project, thanks again for your time!

1 Like