Vision XY Chart change shape size

Ignition 8.1.25

I have an XY chart and I selected lines and shapes dataset type. The size of the shapes is a bit large for my liking since I can have hundreds of points. How can I use the configureChart function to adjust the size of these shapes?

1 Like

:nerd_face: Got nerd-sniped.
Should work across multiple datasets and subplots.

def configureChart(self, chart):
	
	size = 6
	
	topPlot = chart.getXYPlot()

	# Create plot list depending if subplots exist				
	if  hasattr(topPlot, 'getSubplots'):
		plotList = topPlot.getSubplots()
	else:
		plotList = [topPlot]
	
	for plot in plotList:
		datasetCount = plot.getDatasetCount()
		for dsIndex in xrange(datasetCount):
			dataset = plot.getDataset(dsIndex)
			renderer = plot.getRendererForDataset(dataset)
			
			for seriesIndex in  xrange(dataset.seriesCount):
				shape = renderer.getSeriesShape(seriesIndex)
				shape.height=size
				shape.width=size
				shape.x = -size/2.0
				shape.y = -size/2.0
				renderer.setSeriesShape(seriesIndex, shape)

Default size of 6

Size of 4

5 Likes

Jordan,

This is better than I hoped. Thanks a ton!

Hi @JordanCClark and All,

Can we disable the shape for those lines in the single dataset? I have one dataset that contains four lines of chart. I'll give an Image for reference. I have Min, Max, Target, and Actual. These are the four Values I have in the dataset. I had to change the line into Line/Shapes in the chart properties. Then, all of the line styles are changed. But I should need to change the Line style for Actual only. Could you please help me to resolve this issue?

In Chart Customizer:


The above one is my dataset. The Manz ID is an X-Axis value, then HC CH5 590mm is the Actual value and threes are max, min, and target values.

Thanks,
Muniyandi D

I'd make a filter to use the specific dataset column names.

def configureChart(self, chart):

	size = defaultSize = 6
	seriesFilter = ['HC CH5 590mm']
	
	topPlot = chart.getXYPlot()

	# Create plot list depending if subplots exist				
	if  hasattr(topPlot, 'getSubplots'):
		plotList = topPlot.getSubplots()
	else:
		plotList = [topPlot]
	
	for plot in plotList:
		datasetCount = plot.getDatasetCount()
		for dsIndex in xrange(datasetCount):
			dataset = plot.getDataset(dsIndex)
			columnNames = list(dataset.getDataSetForSeries(0).getColumnNames())[1:]
			renderer = plot.getRendererForDataset(dataset)
			for seriesIndex, seriesName in enumerate(columnNames):
				if seriesName in seriesFilter:
						size = 0
				else:
					size = defaultSize
				shape = renderer.getSeriesShape(seriesIndex)
				shape.height=size
				shape.width=size
				shape.x = -size/2.0
				shape.y = -size/2.0
				renderer.setSeriesShape(seriesIndex, shape)
3 Likes

Thanks, @JordanCClark for your support. But I got an error whenever this script was run.

Sample Image:

And the mentioned column's data line's shape size is also not reduced.

FYR:

Pink - 'HC CH5 590mm'
Orange - Top - 'Max', Bottom - 'Min'
Green - 'Target'

Thanks,
Muniyandi D

Can you post a export of the window? If the dataset property is bound to something, remove the binding first, to preserve the data. I should be able to take a closer look this afternoon (currently, its 4am here :wink:)

EDIT: Also, what version of Ignition? Just to be sure I'm on the same page.

2 Likes

Thank You @JordanCClark for your reply messages at 4 am. I'll add an example window and one client tag for that chart. Should need to assign the substrate_id column in the tag as "Manz ID" fro that charts.

Chart_dataset_tags.json (96.9 KB)
Chart_Example_Window.zip (45.4 KB)

You can use this to Check and validate which error has throwing while running the script.

Our ignition version is 8.1.33 (b2023101913)

Thanks,
Muniyandi D

2 Likes

Sorry for the late reply. Work requirements are building up...

Anyway, here's a quick and dirty one that will hide series shapes only. No resizing, as, in my limited time, resizing a polygon is a pain. :laughing:

def configureChart(self, chart):

	seriesFilter = ['HC CH5 590nm', 'Target']

	
	topPlot = chart.getXYPlot()

	# Create plot list depending if subplots exist				
	if  hasattr(topPlot, 'getSubplots'):
		plotList = topPlot.getSubplots()
	else:
		plotList = [topPlot]
	
	for plot in plotList:
		datasetCount = plot.getDatasetCount()
		
		for dsIndex in xrange(datasetCount):
			dataset = plot.getDataset(dsIndex)
			columnNames = list(dataset.getDataSetForSeries(0).getColumnNames())[1:]
			renderer = plot.getRendererForDataset(dataset)
			
			# Create a shape to use for hiding a series shape.
			hiddenShape = renderer.getSeriesShape(0)			
			hiddenShape.height = 0
			hiddenShape.width = 0
			hiddenShape.x = 0
			hiddenShape.y = 0
			
			for seriesIndex, seriesName in enumerate(columnNames):	
				if seriesName in seriesFilter:
					renderer.setSeriesShape(seriesIndex, hiddenShape)
3 Likes

Thank you, Mr.@JordanCClark, for your guidance and support. This script is doing what I expected. And Hats off @JordanCClark for your dedication and support to achieve their goals anytime.

Thanks,
Muniyandi D

1 Like

Is there any way to change the Graph line type? For example, I used XY/Shapes Renderer only. So, the lines and shapes showed a series. But, here my doubt is, can we show only shapes for any one line out of four lines? I mentioned it previously in the previous chats.

Thanks,
Muniyandi D

def configureChart(self, chart):

	noShapesFilter = ['HC CH5 590nm']
	noLineFilter = ['Target']
	
	topPlot = chart.getXYPlot()

	# Create plot list depending if subplots exist				
	if  hasattr(topPlot, 'getSubplots'):
		plotList = topPlot.getSubplots()
	else:
		plotList = [topPlot]
	
	for plot in plotList:
		datasetCount = plot.getDatasetCount()
		
		for dsIndex in xrange(datasetCount):
			dataset = plot.getDataset(dsIndex)
			columnNames = list(dataset.getDataSetForSeries(0).getColumnNames())[1:]
			renderer = plot.getRendererForDataset(dataset)
			# Get base stroke and create a hidden version.
			baseStroke = renderer.baseStroke
			hiddenStroke = baseStroke.class(0)
			# Create a shape to use for hiding a series shape.
			hiddenShape = renderer.getBaseShape()		
			hiddenShape.height = 0
			hiddenShape.width = 0
			hiddenShape.x = 0
			hiddenShape.y = 0
			
			for seriesIndex, seriesName in enumerate(columnNames):	
				if seriesName in noShapesFilter:
					renderer.setSeriesShape(seriesIndex, hiddenShape)
				if seriesName in noLineFilter:
					renderer.setSeriesStroke(seriesIndex, hiddenStroke)
1 Like

Thanks, Mr. @JordanCClark. I think you haven't mentioned the "hiddenLine" variable you had passed in the noLineFilter condition. That's why I got an error?

image

1 Like

Probably. I was pretty sleepy when I wrote it. :wink:

Change hiddenLine to hiddenStroke

1 Like

No worries Mr. @JordanCClark ! Sleepy coding is the birthplace of all kinds of creative bugs. :wink: I've updated it to hiddenStroke - it's ready to roll! But I'm facing one small issue with that. The shapes of those columns we mentioned in the noShapeFilter list columns should be hidden. am I correct? However, all column shapes are hidden whenever the script is enabled.

def configureChart(self, chart):
	
	noShapesFilter = ["Min", "Max", "Target"]
	noLineFilter = ["HC Ch5 590nm"]
	
	topPlot = chart.getXYPlot()
	
	# Create plot list depending if subplots exist				
	if  hasattr(topPlot, 'getSubplots'):
		plotList = topPlot.getSubplots()
	else:
		plotList = [topPlot]
	
	for plot in plotList:
		datasetCount = plot.getDatasetCount()
		
		for dsIndex in xrange(datasetCount):
			dataset = plot.getDataset(dsIndex)
			columnNames = list(dataset.getDataSetForSeries(0).getColumnNames())[1:]
			renderer = plot.getRendererForDataset(dataset)
			
			# Get base stroke and create a hidden version.
			baseStroke = renderer.baseStroke
			hiddenStroke = baseStroke.class(0)
			
			# Create a shape to use for hiding a series shape.
			hiddenShape = renderer.getBaseShape()
			hiddenShape.height = 0
			hiddenShape.width = 0
			hiddenShape.x = 0
			hiddenShape.y = 0
			
			for seriesIndex, seriesName in enumerate(columnNames):
			
				if str(seriesName) in noShapesFilter:
					renderer.setSeriesShape(seriesIndex, hiddenShape)
					
				if seriesName in noLineFilter:
					renderer.setSeriesStroke(seriesIndex, hiddenStroke)

Here, I tried to Hide the shapes for which columns I had mentioned in the noShapesFilter list and to reduce the visibility of the line that is mentioned in the noLineFiletr list. But, I'm not hiding the shapes noLineFilter mentioned column.

Example Image:

I hope you can see the white colored line under the green line that was an "HC Ch5 590nm" column mentioned in noLineFilter. The "HC Ch5 590nm" data line hiding is working well. But, the line Shapes was not showing. We had not mentioned that column name in the noShapeFilter List. Then, how is this happening?

Thanks,
Muniyandi D

EDIT: Correct file uploded.

Since you have your charts in separate groups, I reworked Graph_1. This will be a lot easier for you to maintain.
Campaign_Chart_Example_JC.zip (32.4 KB)

  • added custom properties to the Graph_1 group.
  • added propertyChange script to look for changes in the raw data or column names to sort.
  • added datasets to graph and bound them to the custom dataset properties of the group.

The script:

if event.propertyName in ['_rawData', 'lineSeries', 'shapeSeries']:
	dataIn = system.dataset.toPyDataSet(event.source._rawData)
	
	dataHeaders = []
	dataCols = []
	
	linesHeaders = []
	linesCols = []
	
	shapesHeaders = []
	shapesCols = []
	
	lineSeries = [item.strip() for item in event.source.lineSeries.split(',')]
	shapeSeries = [item.strip() for item in event.source.shapeSeries.split(',')]
	
	for i, col in enumerate(dataIn.columnNames):
		newCol = dataIn.getColumnAsList(i)
		if i==0:
			dataHeaders.append(col)
			dataCols.append(newCol)
			if len(lineSeries[0]) > 0:
				linesHeaders.append(col)
				linesCols.append(newCol)
			if len(shapeSeries[0]) > 0:
				shapesHeaders.append(col)
				shapesCols.append(newCol)
		elif col in lineSeries:
			linesHeaders.append(col)
			linesCols.append(newCol)
		elif col in shapeSeries:
			shapesHeaders.append(col)
			shapesCols.append(newCol)
		else:
			dataHeaders.append(col)
			dataCols.append(newCol)
	
	event.source.data = system.dataset.toDataSet(dataHeaders, zip(*dataCols))
	event.source.linesOnlyData = system.dataset.toDataSet(linesHeaders, zip(*linesCols))
	event.source.shapesOnlyData = system.dataset.toDataSet(shapesHeaders, zip(*shapesCols))
1 Like

Hi @JordanCClark , Thanks for your reply. But i have a doubt, are you given a correct sample window. Becoz, there are two templates in the sample window which you are given in the previous reply. Could please re-check that?

Inside of the Sample file,

,

Thanks,
Muniyandi D

Hah! Uploded the wrong one. I'll be into work in a bit and give you the correct one. :laughing:

1 Like

Correct one attached to the post above.

Really and for true... :slight_smile:

1 Like

Hi Mr. @JordanCClark thank you for the correction. your suggestion is the best one. But, in that some issues are there. I did what you suggested to me. But, I faced another issue when opened that on the client. I have four charts in that window. Whenever I enable the checkbox component lines and shapes datasets are enabled and the data dataset has to be disabled. Then the data are showing as I want. but, sometime later the data are disappeared automatically then that will appear at sometimes later. I don't know why this is happening. I will give a sample window of what I have used. Just move your mouse as a zig-zag on the charts, then you can see that.

Sample Image:

Sample window:
Chart_Window.zip (57.5 KB)

Thanks ,
Muniyandi D