Can I bind pen colors in a Chart to a client tag?

We've got lots of embedded charts on our new system. I don't want to use the default colours on the chart customizer though, I want to bind each one to a client tag that is storing a colour value. This way, as we put our new windows through testing and review, if the operators decide they don't like the colours, we only have to change it in one client tag instead of opening up the customizer on every single trend to change them. (Note I'm not talking about dynamically changing pen colours based on values or anything, so I don't think scripting is required?)

But it doesn't seem like there is a nice way to bind these colours. the Foreground Color etc. show as a property of the Chart, but the pen colours seem buried in the customizer.

Scripting is required. My take on it:

Create a dataset tag with pen names and colors.

In the configureChart function of the chart:

	def datasetToDict(dsIn):
		dictOut = {}
		for i in range(dsIn.rowCount):
			dictOut[dsIn.getValueAt(i, 0)] = dsIn.getValueAt(i, 1)
		return dictOut

	colors = datasetToDict(system.tag.readBlocking(['[client]Styles/Chart Color'])[0].value)

	plot = chart.plot
	renderer = plot.renderer
	seriesCount = plot.seriesCount
	#print dir(renderer)
	legends = renderer.legendItems.iterator()
	#for i in legends:
		#print i.label
	
	for i, legend in enumerate(legends):
		renderer.setSeriesPaint(i, colors[legend.label])

image

That said, I'd offload this to a project script, and call it with a tag name for a parameter.

2 Likes

Thanks! and also: Oof! This is when I start regretting our decision to use Ignition...the Java objects are way beyond me. It's frustrating that the foreground color is so easily bound, but not the pen colours.

Create a dataset tag with pen names and colors.

That's probably more complicated than I need, I already have a dataset that is bound to the historical tags, and every trend has different pens, so I don't want the "global" colours to be linked to pen names. But I'll try and work with the chart.renderer object and see if I can make it just do the colours. So odd that I have to run a script on every chart just to set the colours.

If you just want to swap out the color array with your own, you can boil it down to four lines of scripting:

def configureChart(self, chart):
	colors = system.tag.readBlocking(["[client]Colors"])[0].value

	for i in xrange(chart.plot.seriesCount):
		color = colors.getValueAt(i % colors.rowCount, 0)
		chart.plot.renderer.setSeriesPaint(i, color)

That's not bad, considering the immense complexity hiding inside the classic Chart component. Note that the Easy Chart, since it guarantees you'll be displaying a pretty formulaic XY chart, has an auto color list property exposed:

2 Likes

You may also consider using a template, if the charts are similar in use.

My luck usually runs that, if I had given you my original simplified one, similar to Paul's, you would have asked if it could be tied to pen names. :laughing:

1 Like

Ok, got it! Now next challenge, to discover if the background colour of the legend is hiding in here somewhere...
image

image

1 Like