Change color in a SVG used in SCADA Widget

Dear all

Product/components used and version/fix level:

I’m using Cumulocity IOT Platfrom Trial Version.

Detailed explanation of the problem:

I would like to change the color of a circle in SCADA Widget (SVG) based on a measurement. I can show and update the measurement in the SCADA Widget (SVG), but the color of a circle is not changing.

As described under “Preparing SVG files for the SCADA widget” I have tried to prepare an SVG-File with AngularJS directives. But the detailed notation in SVG/XML is unclear for me.

I have tried to use ng-if for the red circle and ng-style for the black circle, to change the color. The color is not changing, for sure the notation is not correct. Is there somewhere a more detailed guideline or an example, how to change color related to measurement threshold?
Please find the SVG xml code below.

**<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   width="210mm"
   height="297mm"
   viewBox="0 0 210 297"
   version="1.1"
   id="svg14158"
   inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
   sodipodi:docname="HMI_Test.svg"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">
 

    <text
       xml:space="preserve"
       style="font-size:11.2889px;fill:#ec2621;stroke:#000000;stroke-width:0.264583;fill-opacity:1"
       x="51.755302"
       y="53.897205"
       id="text14288"><tspan
         sodipodi:role="line"
         id="tspan14286"
         style="font-size:11.2889px;stroke-width:0.264583;fill:#ec2621;fill-opacity:1"
         x="51.755302"
         y="53.897205">{{c8y_Humidity}}</tspan></text>


  <ellipse
       style="fill:#ec2621;fill-opacity:1;stroke:#000000;stroke-width:0.264583"
       id="path14707"
       cx="100"
       cy="100"
       rx="30"
       ry="30"
       ng-if="c8y_Humidity>'50';fill:blue" />

<ellipse
       ng-style="fill: c8y_Humidity >'50' ? #ec2621 :#ec1821"
       id="path14707"
       cx="150"
       cy="150"
       rx="30"
       ry="30"/>
     
</svg>
**

Error messages / full error message screenshot / log file:

The color of the circles are not updating related to the measurement. Does any body has an example or knows what is the detailed notation in SVG/XML?

Thank you.

Regards

Hi!

I have tried to do what you mention in your topic. This is my code:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
// {{placeholderValue}}
<svg
   width="210mm"
   height="297mm"
   viewBox="0 0 210 297"
   version="1.1"
   id="svg1"
   inkscape:version="1.3.1 (91b66b0783, 2023-11-16)"
   sodipodi:docname="Circle_ChangeColor1.svg"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">
  <sodipodi:namedview
     id="namedview1"
     pagecolor="#ffffff"
     bordercolor="#000000"
     borderopacity="0.25"
     inkscape:showpageshadow="2"
     inkscape:pageopacity="0.0"
     inkscape:pagecheckerboard="0"
     inkscape:deskcolor="#d1d1d1"
     inkscape:document-units="mm"
     inkscape:zoom="0.7180275"
     inkscape:cx="396.22438"
     inkscape:cy="560.56349"
     inkscape:window-width="2400"
     inkscape:window-height="1261"
     inkscape:window-x="2391"
     inkscape:window-y="-9"
     inkscape:window-maximized="1"
     inkscape:current-layer="layer1"
     showguides="false" />
  <defs
     id="defs1" />
  <g
     inkscape:label="Capa 1"
     inkscape:groupmode="layer"
     id="layer1">
    <circle
       stroke-width:0.529166
       style="{{placeholderValue < 50 ? 'fill:#00ff00;stroke-width:0.529166' : 'fill:#ff0000;stroke-width:0.529166'}}"
       id="path1"
       cx="103.17618"
       cy="139.65633"
       r="84.014885" />
  </g>
</svg>

You can save it as a .SVG file and use it as an example.

I tell you that the previous code allows you to change the color, specifically if it is greater than 50 it is red and if it is less it becomes green. This can be modified as needed.

Where should you look to understand the color change condition? On the next line:

style=“{{placeholderValue < 50 ? ‘fill:#00ff00;stroke-width:0.529166’ : ‘fill:#ff0000;stroke-width:0.529166’}}”

This line tells us that if the “PlaceHolderValue” is less than 50 then it will be painted green (#00ff00), on the contrary if it is not met it will be painted red (#ff0000).

I hope my answer has been helpful to you, if you have any additional questions, do not hesitate to let me know.

PS: Use Inkscape to create the circle, then save it as .SVG. Any subsequent modifications to the source code were opened from a notepad. :smiley: `

1 Like

@Reiser_Anthony_Flores_Roca
Thank you for the code. That helped a lot.

Do you know how I can use the “IF” statement?
Something like this, but it is not working on the platfrom:

 <rect
     style="fill:#e5544a;stroke-width:0"
     id="Füllstand"
     width="19"
     height="48"
     if="{{c8y_Pressure > 50 ; 'height="10"'}}"     
     x="108.51614"
     y="37.651993" />

I would like to change the height of a rect, when a measurement reaches a setpoint.

Regards

Looking at the online docs it shows that the svg syntax supports AngularJS directives, so technically you could use the ng-if however it wouldn’t work in the way you are expecting it. Generally an ng-if is used to control whether the element (in this case the <rect> element) is included in the svg image or not. The ng-if is not intended to work on a single property of the element.

However the good news is that you can just use the same syntax used in to set the style property, but applying this to the height property using a simple ternary operator.

For example, if you just want to control the value of the height property based on the c8y_Pressure, then the following snippet can be used:

height="{{c8y_Pressure > 50 ? '10' : '48'}}"

The above height will be set under the following conditions:

  • When c8y_Pressure > 50, height will be 10
  • When c8y_Pressure <= 50, height will be 48

Taking the snippet and applying it to the <rect> element, gives you:

<rect
    style="fill:#e5544a;stroke-width:0"
    id="Füllstand"
    width="19"
    height="{{c8y_Pressure > 50 ? '10' : '48'}}"
    x="108.51614"
    y="37.651993" />

However if you are curious how the example would look if you wanted to used ng-if, then the following should do the same thing visually, but under the hood, two different rect elements are being used, and only one variant is being shown at a time.

<!-- This rectangle will be used when 'c8y_Pressure > 50' -->
<rect
    ng-if="c8y_Pressure > 50"
    style="fill:#e5544a;stroke-width:0"
    id="Füllstand"
    width="19"
    height="10"
    x="108.51614"
    y="37.651993" />

<!-- This rectangle will be used when 'c8y_Pressure <= 50' -->
<rect
    ng-if="c8y_Pressure <= 50"
    style="fill:#e5544a;stroke-width:0"
    id="Füllstand"
    width="19"
    height="48"
    x="108.51614"
    y="37.651993" />
1 Like