[BUG-6988]Embedded View "Template" Instance Behavior

Hello,

I have a very simple embedded view that I wanted to use as a "template" for all of the valves throughout the project. However, the "instances" are not behaving as I expected.

I have a very simple flex container view with one (input) parameter state and a gate valve SVG from the Symbol Factory.

The gradient colors are determined by bindings to the state parameter, like so:
image

This works in the view to get the desired states:
image

The issue arises when I attempt to add it as an embedded view. The first instance behaves correctly, but additional instances mirror the state of the first instance, regardless of it's own state.
image

image

image

image

Am I missing something?

I need to know where the binding resides in order to attempt replication. Where within the elements object is your binding?

gate_valve.props.elements[1].elements[0].elements[0].style.stopColor

You're right, something is broken here. I'll open a ticket to investigate and repair the issue, but it'll likely be some time before we can provide a fix with so many out due to the holidays.

I do have an open ticket (#68096) that I started because I thought I was having a more specific issue with gradients, but the issue seems to be more broad than I expected.

Okay, I've reached out to Support, and they have a draft going through analysis for this.

It seems like this is an issue with how the SVGs handle gradients.

As a workaround I've duplicated the SVG Group, once for each desired color. Then go through and change the gradient ID's for each group and add a visibility property.

You could always just not use gradients, and therefore also comply more with the HMI standards out there :slight_smile:

Also, switch is very difficult to read (I would advocate for its removal from the expression language altogether). I would highly recommend using case instead, for you and future engineers

I am in no way an expert, but I've been diving into SVG and maybe my two cents will be helpful:

You may not need to change the child element id's and instead it may be sufficient to define the parent SVG element's id property. If I were doing this in Javascript the unique access point would be the parent SVG id.

Feel free to completely ignore this :grinning:

The data-component-path is not an id in the strictest sense, but our long-term solution will probably include using that very path as part of the id attribute in use by the children because the data-component-path is guaranteed to be unique.

The problem we have to watch out for however, is some svgs define classes internally and target their children by the id attribute. The "solution" above would break any such svgs, in that they would no longer appear as expected. Working around this behavior is going to be the difficult part as we're in a very dangerous and brittle area.

Is there a particular structure of SVG that will work in the current version? It would be best if I can implement embedded views with SVGs that can change color. Without the state change capability the only option I can see is to directly copy and paste SVG objects onto the parent coordinate view.

The SVGs that I encountered this issue with utilize two < defs > tags, one to define a set of colors and a second to define groups of paths. The final tag is a < use > where I dynamically choose which path group to display. When I place bindings on the color set in the first < defs > tag, I run into the issue described in this bug report.

Is there another way I can construct my SVG that will allow color state change bindings to operate with an embedded view?

To get an SVG to work in the current version, you need to not have duplicate svgs where their definition contains any reference to a hard-coded id and your goal is to change their color.

Any svg which contains color definitons inside of the svg in a manner like this: style="fill: url("#s0_3-SVGID_1_");" will result in this issue because they're defining their appearance (fill, in this case) based off of a specific id present in the DOM. When they search for that id, they will always find the first instance and use that color.

To address this issue in the current version, I used a 'multistate indicator' approach. I created one SVG that contains individual definitions for all possible states. In my case there are 4 conveyor segment types, with 16 state colors, and 3 options for highlight. There are ~200 SVG definitions in the one object. Then I used a binding in conjunction with supporting data in the view's custom parameters to generate the href for a single < use > tag.

For example, there are numeric values representing type, state, and highlight and there are supporting arrays which map those numbers to string ids. I then generate an href like 'straight-running-highlight' which represents the unique id value in the SVG definitions.