# Set X-Trace on Easy Chart to specific date/time

**URL:** <https://forum.inductiveautomation.com/t/set-x-trace-on-easy-chart-to-specific-date-time/81944>\
**Category:** Ignition\
**Tags:** ignition81, vision\
**Created:** [November 15, 2023, 6:39pm UTC](https://forum.inductiveautomation.com/t/set-x-trace-on-easy-chart-to-specific-date-time/81944 "2023-11-15T18:39:55Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![bschroeder](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bschroeder/32/13260_2.png) [@bschroeder](https://forum.inductiveautomation.com/u/bschroeder)\
**Post date:** [November 15, 2023, 6:39pm UTC](https://forum.inductiveautomation.com/t/set-x-trace-on-easy-chart-to-specific-date-time/81944/1 "2023-11-15T18:39:55Z")

</div>

Can the X-Trace marking on the Easy Chart be set to a specific date and time?  
I've been digging around in the API and I can't seem to find a way to specify the X-Trace via scripting.

I've got a customer who wants to show an alarm journal underneath the historian screen, and if an alarm is clicked on, then show/move the X-Trace marking to the date and time of the alarm.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [November 15, 2023, 6:46pm UTC](https://forum.inductiveautomation.com/t/set-x-trace-on-easy-chart-to-specific-date-time/81944/2 "2023-11-15T18:46:49Z")

</div>

This sort of thing is exactly what my NoteChart module was designed to support, including the scriptable XTrace timestamp. (I'd show the alarm events as notes, though, to save screen real estate.)

> **[Ignition Third-Party Module Showcase](https://inductiveautomation.com/moduleshowcase/module/automation-professionals-llc-notechart)**
>
> Easily extend Ignition's core functionality with Third-Party Modules. The Module Showcase is a great place to find a solution that best meets your needs.

---

<div class="post-metadata">

**Author:** ![bschroeder](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bschroeder/32/13260_2.png) [@bschroeder](https://forum.inductiveautomation.com/u/bschroeder)\
**Post date:** [November 15, 2023, 6:49pm UTC](https://forum.inductiveautomation.com/t/set-x-trace-on-easy-chart-to-specific-date-time/81944/3 "2023-11-15T18:49:09Z")

</div>

Thanks for the info. I'll pass that along to them and see what they say.

Can you share any way I can set the XTrace on the IA Supplied EasyChart? Or is there no easy way to do it natively?

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [November 15, 2023, 7:46pm UTC](https://forum.inductiveautomation.com/t/set-x-trace-on-easy-chart-to-specific-date-time/81944/4 "2023-11-15T19:46:23Z")

</div>

> [@bschroeder](#):
>
> no easy way to do it natively?

I honestly would have expected changing the plot's domainCrosshairValue to move the xTrace, but I couldn't get it to work event with a repaint. What I did get to work was calculating the x-coordinate from the domain location and simulating a mouse click using robot. Here is the custom method I developed that simply requires the specified date in millis to be passed in:

```auto
def setXTrace(self, timeStampInMillis):
	from java.awt import Robot
	from java.awt.event import MouseEvent
	
	# Get the internal EasyChart Class, the JFreeChart, and the plot
	chartField = self.getClass().getDeclaredField('chart')
	chartField.setAccessible(True)
	easyChartPanel = chartField.get(self)
	chart = easyChartPanel.chart
	plot = chart.plot
	
	# Calculate the x-coordinate based on the time in millis
	xCoordinate = int((timeStampInMillis - plot.domainAxis.lowerBound) / (plot.domainAxis.upperBound - plot.domainAxis.lowerBound) * easyChartPanel.width)
	
	# Create a robot for simulating mouse events
	robot = Robot()
	
	# Simulate a mouse click event at the calculated x-coordinate within the easyChart
	robot.mouseMove(easyChartPanel.locationOnScreen.x + xCoordinate, easyChartPanel.locationOnScreen.y)
	robot.mousePress(MouseEvent.BUTTON1_MASK)
	robot.mouseRelease(MouseEvent.BUTTON1_MASK)

```

Alternatively, you could simply draw a value marker on the chart to mark the location of the alarm event. Here is an example I developed for the easy chart that you could possibly adapt to your requirement:

> [@Two X-Trace on Easy Chart](https://forum.inductiveautomation.com/t/two-x-trace-on-easy-chart/80938/3):
>
> Well, this is Vision, so just about anything that is not included with the module is theoretically possible if you are willing to build it yourself. The only question is how deep down the rabbit hole a developer is willing to go to get the result they want. In this case, the crosshair could be created with a value marker, and the labels could be created with xy text annotations. If you only ever need two x traces at the same time, then I would create a custom property on the parent container of…

---

<div class="post-metadata">

**Author:** ![bschroeder](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bschroeder/32/13260_2.png) [@bschroeder](https://forum.inductiveautomation.com/u/bschroeder)\
**Post date:** [November 15, 2023, 7:48pm UTC](https://forum.inductiveautomation.com/t/set-x-trace-on-easy-chart-to-specific-date-time/81944/5 "2023-11-15T19:48:43Z")

</div>

Thanks, I'll take a look at those as well.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [November 19, 2023, 8:17am UTC](https://forum.inductiveautomation.com/t/set-x-trace-on-easy-chart-to-specific-date-time/81944/6 "2023-11-19T08:17:33Z")

</div>

In case you are still curious, I figured out that it's the chart panel's `setAnchor` method that can be used to programmatically set the xTrace. However, it's not exposed, so reflection has to be used to invoke it, and it uses a `Point2D.Double` to position the range and domain crosshairs. Therefore, just like the robot method I developed, any timestamp has to be converted to a x coordinate to correctly position the domain crosshair on the chart. Also, in my testing, I found that a repaint is needed to make the effect immediately observable.

---

<div class="post-metadata">

**Author:** ![bschroeder](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bschroeder/32/13260_2.png) [@bschroeder](https://forum.inductiveautomation.com/u/bschroeder)\
**Post date:** [November 19, 2023, 1:25pm UTC](https://forum.inductiveautomation.com/t/set-x-trace-on-easy-chart-to-specific-date-time/81944/7 "2023-11-19T13:25:58Z")

</div>

Thanks!

I've not had enough time to take a look. Next week should be slower though and I should be able to try it.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [November 19, 2023, 10:43pm UTC](https://forum.inductiveautomation.com/t/set-x-trace-on-easy-chart-to-specific-date-time/81944/8 "2023-11-19T22:43:55Z")

</div>

I found some time this morning to install the note chart module in my test environment, and that is by far the simplest approach. All you have to do to move the xTrace is change the traceTS parameter, and it takes a normal and natural date without any convert to millis or x-coordinate hocus pocus:

```auto
newDate = # Alarm event active time
event.source.parent.getComponent('Easy Note Chart').traceTS = newDate

```

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [November 28, 2023, 3:59am UTC](https://forum.inductiveautomation.com/t/set-x-trace-on-easy-chart-to-specific-date-time/81944/9 "2023-11-28T03:59:45Z")

</div>

It came to my attention that the xCoordinate calculation for the robot method listed above could be a little off due to the variable plotData position within the chartPanel. This can be corrected easily with the screenDataArea, but messing around with it, the approach didn't feel complete because of these reasons:  
• The mouse cursor jumping to the chart and not staying at the click point was a bit jarring  
• If the alarm date wasn't displayed on the chart the mouse cursor would move off screen  
• If the chart wasn't already in xTrace mode, nothing would happen.

The following updated approach corrects all of those issues, centers the alarm date on the chart, and puts the xTrace there without the need for any complicated calculations. It also takes a normal unformatted date:

```auto
#def setXTrace(self, date):
	'''
	This is designed to be placed in a custom method on the chart itself
	'''
	from java.awt import Robot, MouseInfo
	from java.awt.event import MouseEvent
	
	# Get the mouse's current location, so it can be put back after the chart has been clicked
	eventLocation = MouseInfo.getPointerInfo().location
	
	# Ensure that the chart is in xTrace mode
	self.setMode(4)
	
	# Reposition the plot, so the selected date and time is centered
	# ...with exactly one day's worth of data visible
	startDate = system.date.addHours(date, -12)
	endDate = system.date.addHours(date, 12)
	self.startDate = startDate
	self.outerRangeStart = startDate
	self.endDate = endDate
	self.outerRangeEnd = endDate
	
	# Get the internal EasyChart class
	easyChartPanel = self.getComponent(0).getComponent(0)
	
	# Get the data area and calculate the coodinates for the exact midpoint of the plotted data
	# ...using the data area bounds and the chart's location on the screen
	dataArea = easyChartPanel.screenDataArea
	xCoordinate = int(easyChartPanel.locationOnScreen.x + dataArea.x + (0.5 * dataArea.width))
	yCoordinate = int(easyChartPanel.locationOnScreen.y + dataArea.y + (0.5 * dataArea.height))
	
	# Create a robot instance
	robot = Robot()
	
	# Ensure that the mouse is not still being pressed by the user before moving the cursor
	# ...This line was added to correct a behavior that occurred during testing
	robot.mouseRelease(MouseEvent.BUTTON1_MASK)
	
	# Move the mouse to the midpoint of the plot
	robot.mouseMove(xCoordinate, yCoordinate)
	
	# Click the mouse button to move the xTrace
	robot.mousePress(MouseEvent.BUTTON1_MASK)
	robot.mouseRelease(MouseEvent.BUTTON1_MASK)
	
	# Move the mouse back to its starting location
	robot.mouseMove(eventLocation.x, eventLocation.y)

```
