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"]
try:
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))
except:
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.