[FEATURE] Perspective Power Chart - Make x-trace box more intuitive

It's been a while since I made a fuss about the Power Chart in Perspective, but my frustrations with it are well and truly all still there..

Another one to add to the list:
The x-trace box is not very intuitive or user-friendly. When you have a lot of pens, it's difficult to identify which pen is which without a link of the label/value to the pen trace. In other platforms, there are either separate boxes with a line that extends to the pen trace, or the label/value font colour matches the pen trace. Adding a coloured box beside each label would work as well. I know I can look at the legend, but having to have to always look at the legend, the x-trace box, and the chart just to decipher the chart is exhausting. This should be the easy part, leaving all mental capacity to analyse the charts instead of having to use it up trying to read it.


I've had the same exact complaint from some of our operators.

My solution was to use CSS to color the pens names the same as the actual color of the pen. Haven't heard a complaint since.

I can post the css tomorrow if you're interested

Edit: Actually... I don't use the power chart. So my css may or may not apply here :thinking:

1 Like

That looks a tonne better than it looks by default! I'll be very interested to see how you did it, and see if I can apply it to the Power Chart as well.

you cant rly know which colors the pen have... but if they have a fixed order and color this could work

(you have to start with 2)

.ia_timeMarker g g g:nth-child(2) .ia_powerChartComponent__xTrace__box__label tspan{
    fill: red;

.ia_timeMarker g g g:nth-child(3) .ia_powerChartComponent__xTrace__box__label tspan{
    fill: blue;

or you could also give the pens a fixed color through stylign to match i guess

(here you do start from 1)

.chart-row.ia_chartRow .ia_lineChart:nth-of-type(1) path  {
    stroke:red !important
.chart-row.ia_chartRow .ia_lineChart:nth-of-type(2) path  {
    stroke:blue !important

.flexBodyInnerScrollContainer .ia_table__body__row:nth-of-type(1) .pen-visibility-checkbox{
    fill:red !important

.flexBodyInnerScrollContainer .ia_table__body__row:nth-of-type(2) .pen-visibility-checkbox{
    fill:blue !important

Looks like @victordcq beat me to it!

Here's how I'm doing it on a TimeSeriesChart:

Just like Victors, you need to change the N to a number starting with 2.

.psc-TrendXTraceStyle_default_grouped .ia_timeMarker > g > g > g > g:nth-child(N) > text:nth-child(1) {fill: #0000D9 !important}
.psc-TrendXTraceStyle_default_split .ia_chartContainer > g:nth-child(3) > g > g:nth-child(2) > g > g:nth-last-child(1) > g > g > g > g > g:nth-child(N) >  text:nth-child(1) {fill: #0000D9 !important}

^---- I'm also sure those css rules could be cleaned up. I suck at CSS.

For having them dynamic per user, I give operators the ability to change their colors but tell them they need to wait a short period of time then logout / log in for them to take effect.

To accomplish this I have a value change script on a dataset tag we have to hold user colors that updates a file in our themes folder:

Dataset has 2 columns: UserName and Colors (json encoded string containing a list of colors)

Tag value change script:

logger = system.util.getLogger('Tag_User_NonDefaultTrendColors')
# File params
folderPath = r'\\servername\c$\Program Files\Inductive Automation\Ignition\data\modules\com.inductiveautomation.perspective\themes\light-custom\common'
fileName = 'time-series-chart-dynamic-xtrace.css'
filePath = '{}\{}'.format(folderPath, fileName)
# Default colors
defaultColors = ["#0000D9","#D900D9","#00D9D9","#00D900","#D9D900","#D97700","#D90000","#B45BFF"]
	if previousValue and currentValue:
		pV = dict(system.dataset.toPyDataSet(previousValue.value))
		cV = dict(system.dataset.toPyDataSet(currentValue.value))
		# if our dictionaries are different, update our file
		if pV != cV:				
			# Convert color string back to it's list counterpart
			for key, value in cV.iteritems():
				cV[key] = system.util.jsonDecode(value)
			# Add Default value to our dictionary
			cV['default'] = defaultColors
			# Build our style classes (split and grouped trends) for each user & the default
			styles = []
			for style in cV:
				for idx, color in enumerate(cV[style]):
					styles.append((".psc-TrendXTraceStyle_%s_grouped .ia_timeMarker > g > g > g > g:nth-child(%s) > text:nth-child(1) {fill: %s !important}" % (style, idx+2, color)))
				for idx, color in enumerate(cV[style]):
					styles.append(".psc-TrendXTraceStyle_%s_split .ia_chartContainer > g:nth-child(3) > g > g:nth-child(%s) > g > g:nth-last-child(1) > g > g > g > g > g:nth-child(2) >  text:nth-child(1) {fill: %s !important}" % (style, idx+2, color))
			styles = '\n'.join(styles)
			# Write to our file / overwriting existing changes
			system.file.writeFile(filePath, styles, False)
			logger.info("{} successfully updated".format(fileName))
	logger.info("There was an error updating file")

The code writes css rules for all users in my dataset tag, as well as the rules for the default colors.

I then have a binding on style.classes for my TimeSeriesChart that adds the required style class in. Default or the users style for grouped / split charts.

1 Like

updating the file.css actually gets picked up fast enough for it to load in? hehe thats neat to know.
i tried modifing some views before but it only gets loaded in after like 5 minutes

Yeah i believe the css files are pulled in when a user logs in, but don't quote me on that.

All i know is that when i log out and back in after changing my colors it works. haha

I was wrong. Takes a short period of time to take effect.

if you treat it like a theme you might be able to get away with not having to log in. as a theme change does try to look for css files... but idk if the gateway will pick them up or if you will need to wait those 5 minutes

edit: heh it might work fast enough its not instant, but if you put in a tiny delay its probably faster than relogging (10 sec seems to be enough, 5 not)

you're right. I apparently was misremembering :thinking:

no you'll need a relog if you didnt change the theme/ themes filename

Looks great. How did you get the seconds in the date/time? I've been digging in the CSS to find that for power chart. Though I see you mention that this isn't a power chart. @nminchin, do you have this problem also? The default x-trace only shows down to minutes.

Yes, it's another issue Ive mentioned already to IA