# Dynamically changing SVG element stroke via scripting

**URL:** <https://forum.inductiveautomation.com/t/dynamically-changing-svg-element-stroke-via-scripting/72003>\
**Category:** Ignition\
**Created:** [April 4, 2023, 8:02am UTC](https://forum.inductiveautomation.com/t/dynamically-changing-svg-element-stroke-via-scripting/72003 "2023-04-04T08:02:16Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![andrewbrown](https://avatars.discourse-cdn.com/v4/letter/a/a8b319/32.png) [@andrewbrown](https://forum.inductiveautomation.com/u/andrewbrown)\
**Post date:** [April 4, 2023, 8:02am UTC](https://forum.inductiveautomation.com/t/dynamically-changing-svg-element-stroke-via-scripting/72003/1 "2023-04-04T08:02:16Z")

</div>

Hi All,

I am trying to set a stroke property of an svg based on the element name.  
i can parse the structure and get the correct property path but cant seem to set the property value.

```auto
def transform(self, value, quality, timestamp):
	row = value.split('B')[0]
	root = self.getChild("root").getChild("WarehouseLocation").props.elements[1].elements
	returnParam=''
	for x in range(len(root)):
		if root[x]['id'] == row:
			
			for y in range(len(root[x]['elements'])):
				if root[x]['elements'][y]['id'] ==value:
					returnParam += "["+str(x) +"].elements["+str(y)+"].stroke.paint"
	
	#This returns (as a string) self.getChild("root").getChild("WarehouseLocation").props.elements[1].elements[10].elements[3].stroke.paint			
	'self.getChild("root").getChild("WarehouseLocation").props.elements[1].elements' + returnParam = '#00FF00'
	

```

any thoughts about setting this string which is the property we want to change?

---

<div class="post-metadata">

**Author:** ![user77](https://avatars.discourse-cdn.com/v4/letter/u/a183cd/32.png) [@user77](https://forum.inductiveautomation.com/u/user77)\
**Post date:** [April 4, 2023, 9:31pm UTC](https://forum.inductiveautomation.com/t/dynamically-changing-svg-element-stroke-via-scripting/72003/2 "2023-04-04T21:31:54Z")

</div>

Hello Andrew,

You can try using exec to compile your path and set it's value.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/9/c/9cebd425c46e315141643718d993b8121e396a98.png)

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/c/8c3b49202ecd7e832b360cf9fde5e3a3a11851a7.png)

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [April 10, 2023, 4:26pm UTC](https://forum.inductiveautomation.com/t/dynamically-changing-svg-element-stroke-via-scripting/72003/3 "2023-04-10T16:26:15Z")

</div>

Eww, no, don't _ever_ use `exec` or `eval`.  
In this particular case, just store the indices you care about in separate variables:

```python
def transform(self, value, quality, timestamp):
	row = value.split('B')[0]
	root = self.getChild("root").getChild("WarehouseLocation").props.elements[1].elements
	returnParam=''

	xIndex = None
	yIndex = None
	for x in range(len(root)):
		if root[x]['id'] == row:
			for y in range(len(root[x]['elements'])):
				if root[x]['elements'][y]['id'] ==value:
					yIndex = y
					xIndex = x

	if xIndex is not None:
		self.getChild("root").getChild("WarehouseLocation").props.elements[1].elements[xIndex].elements[yIndex].stroke.paint = '#00FF00'

```

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [April 11, 2023, 1:12am UTC](https://forum.inductiveautomation.com/t/dynamically-changing-svg-element-stroke-via-scripting/72003/4 "2023-04-11T01:12:03Z")

</div>

> [@paul-griffith](#):
>
> don't _ever_ use `exec` or `eval`

I have a Vision script I am developing to build a dataset with string component paths that can be nested to any depth, and I had intended to use eval to get the components using these paths. Is there a problem with doing this?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [April 11, 2023, 1:18am UTC](https://forum.inductiveautomation.com/t/dynamically-changing-svg-element-stroke-via-scripting/72003/5 "2023-04-11T01:18:54Z")

</div>

Is it something that could be done with getattr? I'd have to see the snippet to say for sure.

In general, it's the same risk as sql injection; if you're accepting user input, it's a bad idea. It's also awful for performance, though that's very unlikely to really matter here.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [April 11, 2023, 3:13am UTC](https://forum.inductiveautomation.com/t/dynamically-changing-svg-element-stroke-via-scripting/72003/6 "2023-04-11T03:13:16Z")

</div>

> [@paul-griffith](#):
>
> same risk as sql injection

Thanks, that makes sense. This script is back end and not affected by user input, but I am curious if there is a better way. However, to avoid dragging this thread too far off of topic, I've created a separate thread here to discuss this matter in more detail:

> [@Use of Eval to getComponents: Is there a better approach for assembling a dynamic component list?](https://forum.inductiveautomation.com/t/use-of-eval-to-getcomponents-is-there-a-better-approach-for-assembling-a-dynamic-component-list/72282):
>
> I'm in the process of refactoring an old script that uses a dataset to get components of various nested depths. The dataset is created at initialization, so it always precisely reflects the items that are in the Vision window. There are two problems with this that I want to fix: • The component list only goes three levels deep • Later when another function uses the data, the code is structured in a way that repeats itself. The sanitized code resembles this: if levelSelectData == "1": selec…
