Classic Chart (XY chart) X-Trace X-axis format

I have a classic XY chart in my Vision application that currently shows the elapsed time in the x-axis (in minutes). It achieves this by having 2 datasets (called data and rawHistory, with rawHistory bound to the Tag History for several tags):

image

and using a propertyChange script to take the rawHistory timestamp, subtract it from the current time to get an elapsed time in milliseconds and putting that information into the data dataset:

if event.propertyName == "rawHistory": 
	rawData = event.newValue 

	headers = list(rawData.getColumnNames()) 
	newData = [] 

	pyData = system.dataset.toPyDataSet(rawData) 
	now = system.date.now().time 

	for row in pyData: 
		t_stamp = row[0].time 
		
		# (Timestamp - Now) = Negative Milliseconds 
		msAgo = t_stamp - now 
		
		# Create the new row using the millisecond value 
		newRow = [msAgo] 
		
		for i in range(1, len(row)): 
			newRow.append(row[i]) 
		
		newData.append(newRow) 

	finalDS = system.dataset.toDataSet(headers, newData) 
	event.source.data = finalDS

The chart is then configured to enable only the data dataset (rawHistory dataset is not charted) and to have an Elapsed Time axis for the X-axis:

and the Elapsed Time X-axis format is configured in the Chart Customizer to show in minutes:

This will show the XY chart with elapsed time from 0 to 20 minutes along the x-axis. The problem I have is that when I use the X-trace, it shows the value of the x-axis in milliseconds (-584755.0 in the screenshot below) instead of minutes (ignore the black rectangles - just hiding tag names):

I have found script in this forum to format the y-axis using the getXTraceLabel() extension function but I am new to Python struggling to figure out how to change the format of the x-axis from milliseconds to seconds, or maybe even from milliseconds to time of day. In addition, any script I am finding seem to only format the X-trace labels containing the values (white, green, red and blue labels above) and not the time X-trace label. Can anyone please help?

If you are already manipulating the data to get the elapsed time, why not convert it to minutes right then?

	for row in pyData: 
		t_stamp = row[0].time 
		
		# (Timestamp - Now) = Negative Minutes
		minAgo = (t_stamp - now) / 60000.0
		
		# Create the new row using the minute value 
		newRow = [minAgo] + row[1:]
				
		newData.append(newRow) 
1 Like

Honestly, for whatever reason, I didn’t think of it! Maybe because the solution was mostly from tech support. Also, maybe because it’s right before the holidays! Once I realized that I had missed the decimal place from 60000.0, which meant my values were coming through as integers instead of floats, this worked to get the X-trace label to show in minutes (I also had to change the X axis type from Elapsed Time to Number because the Elapsed Time axis would try to interpret the minutes as milliseconds). However, is there a way to format the X-trace label to show 2 decimal places for the X label? I’d like to keep all the decimal places in the table - I just want to format the label on the X-trace so it doesn’t show a billion decimal places:

1 Like

Sorry for the late reply. The holidays are a busy time for my family, with my daughter home from college for a few weeks. Priorities...

Anyway, rounding the value to 2 places would do it for you:

minAgo = round((t_stamp - now) / 60000.0),2)
2 Likes

I totally understand! I hope you had a great holiday season!

I think my one issue with the solution is that in the table, the values would lose the precision so it’s only drawing the trend to 2 decimal places. I would like the table to still contain all the decimal places but only show 2 decimal places in the X-trace label.

1 Like

This one has me stumped. With a date axis, the lower xTrace label can be modified by changing the plot's dateFormat and timeFormat properties using reflection.

...but in this example, a number axis is being used, and after an exhaustive search, I haven't found any reasonable way to adjust the formatting. Unless somebody is willing to give me a direction to move in, I'm afraid I'm out of ideas.

I provide access to this functionality in my NoteChart module, via the extension method formatTraceValue().

(Although, it also honors the number display format in the axis, which may suffice.)

2 Likes

Does setNumberFormatOverride() not work?

No; it was the first thing I tried. It only changed the tick mark label format on the domain axis, and it had no effect whatsoever on that lower crosshair annotation.

It's been a long time and my recall of the spelunking is a bit hazy...

IIRC, the code path in the IA XTrace implementation simply has no way to override/influence the value label generation. Since I completely rewrote XTrace in NoteChart, I fixed that oversight.

You might be able to layer in a complete rewrite of XTrace in the native components..... :man_shrugging:

It's fairly trivial to generate custom xyTextAnnotations off of the selectedXValue property change event, and the stock range axis values can be hidden with the getXTraceLabel extension function, so there's a lot that can be done to customize the standard xTrace labeling, but that lower domain label is an enigma to me. On a date axis, I can simply hide it with a blank string SimpleDateFormat on the date and time format properties, but I can't even find a way to hide the label when a number axis is being used.

Something like this is within my capability. For example, I could replace the xTrace menu item's action listener to stop it from loading the stock XTrace mode, and then, create my own xTrace mode with a value marker and text annotations, but that's way beyond my tolerance for convolution—especially considering that Jordan's solution is so simple. I would definitely go with his solution over that even if it meant a tiny loss of precision.

Of course. But how does the value of your time compare to my module $$ ?

2 Likes

Oh, your NoteChart module's price point would be a huge savings for anybody required to go down that rabbit hole.

You assume my company counts my time as worth anything. :zany_face:

5 Likes

Thanks so much for your input everyone! I don’t have NoteChart and I’m not sure my company would approve its use (they have strict policies on what software can/cannot be used). I will discuss the loss of precision with my colleagues vs. showing all the decimal places and will pick an option! Really appreciate everyone in this forum for helping (especially since I’m new to Ignition and Python)!

For that conversion the loss of precision would be, at most, 600ms ±300ms.

2 Likes