Range Axis tick density in Status Chart

Hello,
i have a minor cosmetic problem with the range axis in a status chart. In certain resolutions there is no spacing between the labels. I tried to change the font size and the margins without success.
Is there any other setting i can use to tweak this?


What is the range, time stamp? You can try to modify the time stamp to a format that displays smaller. The only other alternative would be to change the width of the chart and changing the font size.

Hi,
thanks for your answer.

The Range is a TimeStamp (UTC milliseconds, converted to DateTime by the DB). I have the chart connected to a date range selector, so the user can modify the range. Also i want the chart to scale with the window. At the moment, if the user changes the size of the window, or selects an other date range, the ticks are automatically adjusted. In most combinations of size and range this works perfect, but as you can see in the screenshot, there are certain situations where Ignition just uses too many ticks.
I was hoping there was a way to tweak the auto scaling somehow.

Another little thing: When the range covers more than a few hours, the time is displayed without minutes (‘10’ instead of ‘10:00’. I head two of my test users call me today asking why the chart suddenly displays half a month (hours where from 01 to 17, so they thought it were the days of month instead of the hours.

I know these are no big problems from a programmers point of view, but for end users it is irritating.

If you would like to attach the window or email it to support@inductiveautomation.com

When you say that the user is only seeing whole hours, it is probably because of how zoomed in they are on the date range selector. I am curious about the date range changing unexpectedly and only showing half of a month. For the tick marks on the X axis, you will not be able to modify them. If you look at another component, say the easy chart, you will see that there is a property for the X Axis Margin. This property would give you the ability to adjust the spacing between tick marks. You could post this to the feature request part of the forum and the developers could add this to the software.

Just in case someone else has users complaining about the DateAxis not looking ‘like in software XYZ’, or international users where the standard date formatting just looks wrong:
Is is possible to overide the Axis to use custom date formats in a script module. This also helps with the missing spaces between the ticks, which seems to be a intermittend problem when using anchored layouts.

Place the following code in a script module and call it in a property change event of the chart.
For further details look at the JFreeChart docs for DateTickUnits.

if event.propertyName == 'propertiesLoading':
	newUnits = app.chartUtils.DateTickUnits(event.source, "Displaying %s to %s")
	system.util.invokeLater(newUnits.setDateTickUnits) 
# put in package app.chartUtils
import app
global app

def setDateTickUnits(chart, label):
	from java.text import SimpleDateFormat
	from org.jfree.chart.axis import TickUnits
	from org.jfree.chart.axis import DateTickUnit
	
	# Create a new org.jfree.chart.axis.TickUnits
	units = TickUnits()
	
	# Format definitions
	# Formats are created with default timezone and default locale
	# format.setTimezone might be used to override the timezone
	# Additional space is added to the format to prevent ticks from being
	# displayed without space (happens sometimes when using anchored layout).
	formatMSec = SimpleDateFormat(" HH:mm:ss SS")
	formatSec = SimpleDateFormat(" HH:mm:ss")
	formatMin = SimpleDateFormat(" HH:mm")
	formatHour = SimpleDateFormat(" HH:mm")
	formatDay = SimpleDateFormat(" dd.MM HH:mm")
	formatMonth = SimpleDateFormat(" dd.MM.yyyy")
	formatYear = SimpleDateFormat(" MMM yyyy")
	
	# Add the units
	units.add(DateTickUnit(DateTickUnit.MILLISECOND, 5, formatMSec))
	units.add(DateTickUnit(DateTickUnit.MILLISECOND, 50, DateTickUnit.MILLISECOND, 5, formatMSec))
	units.add(DateTickUnit(DateTickUnit.MILLISECOND, 250, DateTickUnit.MILLISECOND, 50, formatMSec))
	units.add(DateTickUnit(DateTickUnit.MILLISECOND, 500, DateTickUnit.MILLISECOND, 50, formatMSec))
	units.add(DateTickUnit(DateTickUnit.SECOND, 1, DateTickUnit.MILLISECOND, 50, formatSec))
	units.add(DateTickUnit(DateTickUnit.SECOND, 2, DateTickUnit.MILLISECOND, 250, formatSec))
	units.add(DateTickUnit(DateTickUnit.SECOND, 5, DateTickUnit.MILLISECOND, 250, formatSec))
	units.add(DateTickUnit(DateTickUnit.SECOND, 10, DateTickUnit.MILLISECOND, 500, formatSec))
	units.add(DateTickUnit(DateTickUnit.SECOND, 30, DateTickUnit.SECOND, 2, formatSec))
	units.add(DateTickUnit(DateTickUnit.MINUTE, 1, DateTickUnit.SECOND, 5, formatSec))
	units.add(DateTickUnit(DateTickUnit.MINUTE, 2, DateTickUnit.SECOND, 10, formatMin))
	units.add(DateTickUnit(DateTickUnit.MINUTE, 5, DateTickUnit.SECOND, 30, formatMin))
	units.add(DateTickUnit(DateTickUnit.MINUTE, 10, DateTickUnit.MINUTE, 1, formatMin))
	units.add(DateTickUnit(DateTickUnit.MINUTE, 20, DateTickUnit.MINUTE, 5, formatMin))
	units.add(DateTickUnit(DateTickUnit.MINUTE, 30, DateTickUnit.MINUTE, 5, formatMin))
	units.add(DateTickUnit(DateTickUnit.HOUR, 1, DateTickUnit.MINUTE, 5, formatHour))
	units.add(DateTickUnit(DateTickUnit.HOUR, 2, DateTickUnit.MINUTE, 10, formatHour))
	units.add(DateTickUnit(DateTickUnit.HOUR, 4, DateTickUnit.MINUTE, 30, formatHour))
	units.add(DateTickUnit(DateTickUnit.HOUR, 6, DateTickUnit.HOUR, 1, formatHour))
	units.add(DateTickUnit(DateTickUnit.HOUR, 12, DateTickUnit.HOUR, 2, formatHour))
	units.add(DateTickUnit(DateTickUnit.DAY, 1, DateTickUnit.HOUR, 1, formatDay))
	units.add(DateTickUnit(DateTickUnit.DAY, 2, DateTickUnit.HOUR, 4, formatDay))
	units.add(DateTickUnit(DateTickUnit.DAY, 7, DateTickUnit.DAY, 1, formatDay))
	units.add(DateTickUnit(DateTickUnit.DAY, 14, DateTickUnit.DAY, 1, formatDay))
	units.add(DateTickUnit(DateTickUnit.MONTH, 1, DateTickUnit.DAY, 1, formatDay))
	units.add(DateTickUnit(DateTickUnit.MONTH, 2, DateTickUnit.DAY, 7, formatMonth))
	units.add(DateTickUnit(DateTickUnit.MONTH, 3, DateTickUnit.DAY, 14, formatMonth))
	units.add(DateTickUnit(DateTickUnit.MONTH, 6, DateTickUnit.MONTH, 1, formatMonth))
	units.add(DateTickUnit(DateTickUnit.YEAR, 1, DateTickUnit.MONTH, 1, formatYear))
	units.add(DateTickUnit(DateTickUnit.YEAR, 2, DateTickUnit.MONTH, 3, formatYear))
	
	# Apply the new tick units to the chart
	plot = chart.getChart().getPlot()
	rangeAxis = app.chartUtils.CustomDateAxis(label)
	rangeAxis.setStandardTickUnits(units)
	chart.getChart().getPlot().setRangeAxis(rangeAxis)

# This class is used to set DateTickUnits asynchronous by invokeLater
# Usage in propertyChange script of the chart:
# if event.propertyName == 'propertiesLoading':
#	newUnits = app.chartUtils.DateTickUnits(event.source)
#	system.util.invokeLater(newUnits.setDateTickUnits)  
#
# The chart will be created with the default DateTickUnits. The invokeLater sets the new units
# immediately, but there WILL be a flicker everytime the chart reloads.
class DateTickUnits:
	# Param chart: Reference to the chart
	# Param label: The custom label (see CustomDateAxis) %s will be replaced with start/end date
	def __init__(self, chart, label="%s - %s"):
	   self.chart = chart
	   self.label = label
	   
	def setDateTickUnits(self):
		import app
	 	app.chartUtils.setDateTickUnits(self.chart, self.label)
	 	
# Override DateAxis#getLabel to return min & max date in custom format
from org.jfree.chart.axis import DateAxis
class CustomDateAxis(DateAxis):
	def __init__(self, customLab):
		self.customLab = customLab
	
	def getLabel(self):
		from java.text import SimpleDateFormat
		minDate = super(app.chartUtils.CustomDateAxis, self).getMinimumDate()
		maxDate = super(app.chartUtils.CustomDateAxis, self).getMaximumDate()
		# Modify the format given here, ore add additional logic to change according to the range
		format = SimpleDateFormat(" dd.MM.yyy HH:mm:ss")
		# a custom label might be added to the return string
		return self.customLab % (format.format(minDate), format.format(maxDate))

Would you mind posting a screen shot for comparison?

Here are some screenshots. The upper chart uses the ‘customized’ axis.




Excellent Job!!! :thumb_left:

Nice work, thanks for the contribution! I’m sure others will benefit from it as well.