Add IAT text by using property svgContent of PaperWidget

Good afternoon,
i try to use paper widget and i want to add some text inside my svg content.
I have seen the example on ASH ASHelp online

As far as i’ve understood paperwidget communicate only with plc by opcua server side ..so i think it is impossible to link an IAT text .
for example:

<text class="cText" font-family="Helvetica, Arial, sans-serif" font-size="25" y="380" x="200">$$IAT/Obj1/1</text>


Am i right? Thanks

You are right, using the text system inside the SVG that is being displayed paper widget is not possible. As a workaround you could build the text string inside the PLC using the ArTextSys library to resolve the text. Did this in the past. → This also means you would have to map down the selected language of each device that is connected to the PLC and then resolve it for each device individually.
Or put a Label/TextOutput overlay onto the PaperWidget

@tullio.quirini1
Do you mind me asking what this SVG looks like?

You can actually create an SVG from scratch with any kind of text embedded very easily by using EventScript / mappScript!

Good afternoon Marcel,
sorry for delay but i was busy.. The svg is a P&I Layout. I want to put some label on the object present on the P&I and i’d like to have a solution for simply adapt the project also for different geographic zone (e.g. china, arabia etc..) .. i haven’t used yet the event script of mappscript but i really appreciate if you could give me a usage description (related to my case) or an example. Thanks

Hi Tullio,

it was a bit more complicated than I thought but I have a working example for you.
The tricky part is to read out the TextID into something that can read the actual text not just the TextD.
The basic idea is to display the SVG without text labels using the svgFilePath and the svgContent binding to overlay the text labels wherever they are needed.

Here is what that looks like and how did it:

2026-08-13_13-14-43

My test svg just zipped
TextTest.zip (1.2 KB)

Create some index text labels

image

Create a snippet to read the index text

<Snippet id="SnippetLabel" xsi:type="session" type="IndexText" formatItem="IAT/Label.{1}" />

Greate the necessary bindings for the snippet and svgContent.
The source is a session variable which is used later to read each index text. After going through the snippet, the text is written into another session variable FromLabelText.

    <Binding mode="twoWay">
			<Source xsi:type="session" refId="svgContentText" attribute="value" />
			<Target xsi:type="brease" contentRefId="HD_LS1_contentService3" widgetRefId="Paper1" attribute="svgContent" />
	</Binding>	
    <Binding mode="oneWay">
		<Source xsi:type="session" refId="LabelValue" attribute="value" />
		<Target xsi:type="snippet" refId="SnippetLabel" attribute="value" />
	</Binding>
	<Binding mode="oneWay">
		<Source xsi:type="snippet" refId="SnippetLabel" attribute="value" />
		<Target xsi:type="text" refId="Label" attribute="value" />
	</Binding>
	<Binding mode="oneWay">
		<Source xsi:type="text" refId="Label" attribute="value" />
		<Target xsi:type="session" refId="FromLabelText" attribute="value" />
	</Binding>

We need some session variables

	<Variable name="Language" xsi:type="ANY_INT" value="0" />
	
	<Variable name="LabelValue" xsi:type="ANY_INT" value="0" />
	<Variable name="FromLabelText" xsi:type="ANY_STRING" value="" />
	
	<Variable name="svgContentText" xsi:type="ANY_STRING" value="" />

And for the EventScript the following code

clientSystem.contentLoaded(function(e){
    if (e.detail.contentId === 'HD_LS1_contentService3') {
        var texts = [];

        // Binding chain LabelValue→SnippetLabel→Label(text)→FromLabelText is async; step through via valueChanged
        variables.FromLabelText.valueChanged(function(ev){
            if (texts.length >= 3) { return; }
            texts.push(ev.detail.newValue);
            if (texts.length < 3) {
                variables.LabelValue.setValueNumber(texts.length + 1);
            } else {
                variables.svgContentText.setValueString(buildLabelOverlay(texts[0], texts[1], texts[2]));
            }
        });

        variables.LabelValue.setValueNumber(0);
    }
});

variables.Language.valueChanged(function(e){
    if (e.detail.newValue != e.detail.oldValue) {
        var texts = [];

        // Binding chain LabelValue→SnippetLabel→Label(text)→FromLabelText is async; step through via valueChanged
        variables.FromLabelText.valueChanged(function(ev){
            if (texts.length >= 3) { return; }
            texts.push(ev.detail.newValue);
            if (texts.length < 3) {
                variables.LabelValue.setValueNumber(texts.length + 1);
            } else {
                variables.svgContentText.setValueString(buildLabelOverlay(texts[0], texts[1], texts[2]));
            }
        });

        variables.LabelValue.setValueNumber(0);
    }
});

// Update paperW/paperH when Paper1 is resized; all positions and font size derive from these
var PAPER_W = 320;
var PAPER_H = 550;

// TextTest.svg viewBox dimensions and label rect centers (viewBox units)
var SVG_VB_W = 320;
var SVG_VB_H = 550;
var LABELS = [
    { x: 164, y: 86  },
    { x: 164, y: 266  },
    { x: 164, y: 448 }
];

function buildLabelOverlay(text1, text2, text3) {
    var scale = Math.min(PAPER_W / SVG_VB_W, PAPER_H / SVG_VB_H);
    var xOff  = (PAPER_W - SVG_VB_W * scale) / 2;
    var yOff  = (PAPER_H - SVG_VB_H * scale) / 2;
    var fontSize = Math.round(20 * scale);
    var style = ' font-family="Arial" font-size="' + fontSize + '" text-anchor="middle" dy="0.35em" fill="#1a1a1a"';
    var texts = [text1, text2, text3];
    var result = '';
    for (var i = 0; i < LABELS.length; i++) {
        var px = Math.round(xOff + LABELS[i].x * scale);
        var py = Math.round(yOff + LABELS[i].y * scale);
        result += '<text' + style + ' x="' + px + '" y="' + py + '">' + texts[i] + '</text>';
    }
    return result;
}

The size for paper widget and svg loaded within are defined so the label coordinates are matching. Then the label coordinates, those I just read from the Inkscape’s cursor position when hovering over the center of the rectangle I want to place the label.

Every time the content is loaded or the language is changed the code changes the LabelValue which returns the index text per written into a text array.

That text array is the source for creating a string written into the svgContentText with the internal function using text and coordinates.

You didn’t say how many labels you have or if you are scaling the image in any way but hopefully gives you an example to start with.

wow thank you for the example. It is not easy but the explaination is perfect. Thanks again. I think is a good solution.. i have also learn another powerful aspect of mappview ..thanks