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:

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

Ok, thanks for the suggestion!

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

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

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!