# Display X Value as Label on Easy Chart

**URL:** <https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [July 25, 2025, 5:41pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957 "2025-07-25T17:41:51Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![byutz](https://avatars.discourse-cdn.com/v4/letter/b/b38774/32.png) [@byutz](https://forum.inductiveautomation.com/u/byutz)\
**Post date:** [July 25, 2025, 5:41pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/1 "2025-07-25T17:41:51Z")

</div>

Is there a way to display the x value as a label for each point on an easy chart? I have a tag history dataset, and I want to display the date by each point so the operators can print the chart and have the dates of the points readily available. I have seen some posts on the StandardXYItemLabelGenerator from jfree.charts, but have had no luck implementing. Is there another way, or does anyone have a more comprehensive example? I tried the below code snippet from this [topic](https://forum.inductiveautomation.com/t/display-label-on-each-point-of-an-xychart/23159), but I cant get it to do anything. I am sure I am leaving something out, but can not seem to figure out what. Thank you in advance!

```python
def configureChart(self, chart):
	from org.jfree.chart.labels import StandardXYItemLabelGenerator
	
	class MyLabelGenerator(StandardXYItemLabelGenerator):
		def generateLabel(self, xyds, series, item):
			return "s%dp%d" % (series, item)
	
	renderer = chart.plot.renderer
	renderer.setItemLabelGenerator(MyLabelGenerator())
	renderer.setBaseItemLabelsVisible(True)

```

---

<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:** [July 27, 2025, 12:24am UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/2 "2025-07-27T00:24:03Z")

</div>

Have you considered using [xyTextAnnotations](https://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/annotations/XYTextAnnotation.html)? There are quite a few examples here in the forum of how to implement them. It would probably be easier to control on an easy chart which can have a data point for each visible pixel along the domain axis.

---

<div class="post-metadata">

**Author:** ![byutz](https://avatars.discourse-cdn.com/v4/letter/b/b38774/32.png) [@byutz](https://forum.inductiveautomation.com/u/byutz)\
**Post date:** [July 29, 2025, 4:29pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/3 "2025-07-29T16:29:04Z")

</div>

Thank you for the suggestions, I was able to modify one of your other forum posts to get it working

```python
	from org.jfree.chart.annotations import XYTextAnnotation
	plot = chart.getPlot()
	for annotation in plot.getAnnotations():
		if isinstance(annotation, XYTextAnnotation):
			plot.removeAnnotation(annotation)

	labelData = self.parent.getComponent('Power Table').data
	for row in range(0, labelData.rowCount):
		print row
		text = str(labelData.getValueAt(row, 0))
		startTime = float(labelData.getValueAt(row, 0).getTime())
		x = startTime
		y = labelData.getValueAt(row, 1) + 0.05
		annotation = XYTextAnnotation(text, x, y)
		plot.addAnnotation(annotation)

```

I had to stick the data in a PowerTable component and loop through it to put the dates at the points of the Easy Chart. Is there a way to just iterate through the points already on the Easy Chart? I can make the above work, but would prefer to not have to hide another component on the screen unless necessary.

---

<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:** [July 30, 2025, 1:40pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/4 "2025-07-30T13:40:10Z")

</div>

> [@byutz](#):
>
> but would prefer to not have to hide another component on the screen

When I need this sort of thing, I usually just add a custom property to the parent container.  
**Example:**  
• Right click on the parent container and select "_ **Customizers --\> Custom Properties** _"

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/2/22e0ed7e7ef0d5e032d9c3b22f466b78e8403695.png)

• Click the plus icon on the left, give the new property an intuitive name, and in this case, select the dataset datatype:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/f/ff534666d533c61713ed6c230318afd29954d5bc.png)

**Result:**  
This eliminates the need for a hidden component, and the `labelData = `code becomes simply:

```python
labelData = self.parent.labelData

```

> [@byutz](#):
>
> Is there a way to just iterate through the points already on the Easy Chart?

The path to a jfree chart's xyPlot dataset is simply `chart.plot.dataset`, but for what you're wanting, populating the desired labels directly seems simpler and more maintainable. I would probably just switch from a power table to a custom property to get rid of the hidden component and otherwise keep using your current approach.

---

<div class="post-metadata">

**Author:** ![byutz](https://avatars.discourse-cdn.com/v4/letter/b/b38774/32.png) [@byutz](https://forum.inductiveautomation.com/u/byutz)\
**Post date:** [July 30, 2025, 4:24pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/5 "2025-07-30T16:24:18Z")

</div>

I added the custom dataset property and it works great, thank you! My next issue is that I can only see the labels in Designer, not in Vision. I added some print statements in my configureChart function and when running in vision, it appears to be firing before the data has been received(my rowcount = 0). Should the label creating code not live in configureChart routine? I tried moving it out to a property change event handler, but then I realized I dont know how to get the jfreechart chart object that is easily accessible in the configureChart routine. Is there a way to trigger the configureChart method after the data is loaded?

---

<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:** [July 30, 2025, 4:33pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/6 "2025-07-30T16:33:33Z")

</div>

> [@byutz](#):
>
> how to get the jfreechart chart object

It's always been this:

```python
easyChart.getComponent(0).getComponent(0).chart

```

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [July 30, 2025, 5:19pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/7 "2025-07-30T17:19:51Z")

</div>

> [@byutz](#):
>
> Should the label creating code not live in configureChart routine?

It absolutely should, and I think you're making it far more complicated than it needs to be.

See:

> [@Formatting chart labels in reporting V7.9?](https://forum.inductiveautomation.com/t/formatting-chart-labels-in-reporting-v7-9/38032/6):
>
> Yeah, So I was only providing an example, to show a simple solution for what it would look like. Probably should have just not been lazy and actually included a detailed explanation as well. sweat_smile So for this generator, the MessageFormat ArgumentIndex values correspond to the following: 0 = series name 1 = domain or X-Axis Value 2 = range or Y-Axis Value The number between the ‘{}’ tells the generator which value/s to use in the label output. You can include text that will be t…

I understand that post is from quite a while ago, and different version of the software, but it should still apply.

Try this code:

```python
def configureChart(self, chart):
	from org.jfree.chart.labels import StandardXYItemLabelGenerator
	from java.text import DateFormat
	from java.text import NumberFormat
	
	renderer = chart.plot.renderer
	xFormat = DateFormat.getDateTimeInstance()
	yFormat = NumberFormat.getNumberInstance()
	renderer.setItemLabelGenerator(StandardXYItemLabelGenerator('{1}',xFormat,yFormat))
	renderer.setBaseItemLabelsVisible(True)

```

Note, it won't take many data points for this to become unreadable. You can of course provide a more granular format for the date format.

---

<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:** [July 30, 2025, 8:28pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/8 "2025-07-30T20:28:17Z")

</div>

> [@lrose](#):
>
> it won't take many data points for this to become unreadable.

This would be my biggest concern for this approach with the easy chart.

---

<div class="post-metadata">

**Author:** ![byutz](https://avatars.discourse-cdn.com/v4/letter/b/b38774/32.png) [@byutz](https://forum.inductiveautomation.com/u/byutz)\
**Post date:** [July 31, 2025, 2:46am UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/9 "2025-07-31T02:46:45Z")

</div>

I tried the code snippet in place of what I had in the configureChart routine for my Easy Chart, and i get nothing! My data points still show up, but no labels! I am sure I am missing something but can't figure out what! If this would work it would be great. These data points are only logged once every 3 days, so it wouldn't be messy at all.

---

<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:** [July 31, 2025, 7:58am UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/10 "2025-07-31T07:58:16Z")

</div>

How are you populating your dataset?

---

<div class="post-metadata">

**Author:** ![byutz](https://avatars.discourse-cdn.com/v4/letter/b/b38774/32.png) [@byutz](https://forum.inductiveautomation.com/u/byutz)\
**Post date:** [July 31, 2025, 10:52am UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/11 "2025-07-31T10:52:20Z")

</div>

I drag tags out of the tree and drop them on the easy chart, then i save the page so the pens stay on there permanently.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [July 31, 2025, 11:11am UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/12 "2025-07-31T11:11:58Z")

</div>

Can you please show how this code looks in the configure chart event. And what the tagPens data looks like?

---

<div class="post-metadata">

**Author:** ![byutz](https://avatars.discourse-cdn.com/v4/letter/b/b38774/32.png) [@byutz](https://forum.inductiveautomation.com/u/byutz)\
**Post date:** [July 31, 2025, 12:48pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/13 "2025-07-31T12:48:40Z")

</div>

Of course.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/4/5/452d554c57d93e4c46d471bde015c5c3cb9c812b.png)  
sample of what the data will look like:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/c/d/cdf04fcde026018f986c666ff7ce98af550a39f4.png)  
Current chart config lrose sent that I cant get to work:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/c/2/c211be6a4b40ba8e8714d63f9097d8589ff945da.png)  
Chart config that works in designer but not vision  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/8/282dc0fa4da623faf52feb57419f64e7a9b04335.png)

---

<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:** [July 31, 2025, 2:04pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/14 "2025-07-31T14:04:47Z")

</div>

I still don't see how the `labelData` dataset property is being populated

---

<div class="post-metadata">

**Author:** ![byutz](https://avatars.discourse-cdn.com/v4/letter/b/b38774/32.png) [@byutz](https://forum.inductiveautomation.com/u/byutz)\
**Post date:** [July 31, 2025, 3:54pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/15 "2025-07-31T15:54:33Z")

</div>

Originally it was a dropped pen on the chart, then I set up a custom dataset property on the container(dataForLabels). I bound it to the taghistory of my test tag, and then read that in the chartconfig as

> labelData = self.parent.dataForLabels

. Sorry, I forgot I set that up yesterday. Below is a picture of the data bound to the custom property dataForLabels.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/9/e/9eeba95d8d7365396759bd3437f0991a48e754fd.png)

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [July 31, 2025, 3:55pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/16 "2025-07-31T15:55:19Z")

</div>

How is the pen configured on the Easy Chart

---

<div class="post-metadata">

**Author:** ![byutz](https://avatars.discourse-cdn.com/v4/letter/b/b38774/32.png) [@byutz](https://forum.inductiveautomation.com/u/byutz)\
**Post date:** [July 31, 2025, 4:03pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/17 "2025-07-31T16:03:09Z")

</div>

The pen is set up in the Chart Config-Tag Pens dataset:

![image](https://us1.discourse-cdn.com/inductiveautomation/optimized/3X/f/4/f45b6e514521e46e3ae62a042e3828041246bf70_2_690x44.png)

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [July 31, 2025, 5:26pm UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/18 "2025-07-31T17:26:57Z")

</div>

Okay, the issue appears to be that you are using the Dot Renderer, and it appears that for whatever reason, the dot renderer does not honor the `isLabelItemVisible` attribute.

Try this:

```python
def configureChart(self, chart):
	from org.jfree.chart.labels import StandardXYItemLabelGenerator
	from org.jfree.chart.renderer.xy import XYDotRenderer
	from java.text import DateFormat
	from java.text import NumberFormat
	
	class XYLabeledDotRenderer(XYDotRenderer):
		def drawItem(self,g2,state,dataArea,info,plot,domainAxis,rangeAxis,dataset,series,item,crosshairState,p):
			
			self.super__drawItem(g2,state,dataArea,info,plot,domainAxis,rangeAxis,dataset,series,item,crosshairState,p)
			orientation = plot.orientation
			x = dataset.getXValue(series,item)
			y = dataset.getYValue(series,item)
			xAxisLocation = plot.domainAxisEdge
			yAxisLocation = plot.rangeAxisEdge
			transX1 = domainAxis.valueToJava2D(x,dataArea,xAxisLocation)
			transY1 = rangeAxis.valueToJava2D(y,dataArea,yAxisLocation)
			
			if self.isItemLabelVisible(series,item):
				self.drawItemLabel(g2,orientation,dataset,series,item,transX1,transY1,(y<0.0))
		
		
	if isinstance(chart.plot.renderer, XYDotRenderer):
		chart.plot.renderer = XYLabeledDotRenderer()

	renderer = chart.plot.renderer
	xFormat = DateFormat.getDateTimeInstance()
	yFormat = NumberFormat.getNumberInstance()
	renderer.setItemLabelGenerator(StandardXYItemLabelGenerator('{1}',xFormat,yFormat))
	renderer.setBaseItemLabelsVisible(True)

```

What this does is creates a class XYLabeledDotRenderer, which extendes XYDotRenderer. This class provides the added logic to print the labels.

It will only replace the renderer if the current renderer is an instance of XYDotRenderer.

The Area Renderer has a similar issue.

Otherwise the code should work for any renderer that you select.

If needed, it doesn't take much effort to use a similar method to insure that you only print a lable when the data changes, you would just need to know what type of renderer you were going to use in advance. This would help with keeping the chart looking clean.

---

<div class="post-metadata">

**Author:** ![byutz](https://avatars.discourse-cdn.com/v4/letter/b/b38774/32.png) [@byutz](https://forum.inductiveautomation.com/u/byutz)\
**Post date:** [August 1, 2025, 2:15am UTC](https://forum.inductiveautomation.com/t/display-x-value-as-label-on-easy-chart/108957/19 "2025-08-01T02:15:23Z")

</div>

That worked, thank you so much! I would never have figured that out.
