SvgViewerWidgetTWX
SvgViewerWidgetTWX copied to clipboard
Thingworx widget for runtime display and manipulation of a SVG
SVG viewer for Thingworx
View dynamic responsive SVG files within Thingworx, in order to show plant layouts, floor maps, process diagrams and a wide variety of other usecases.
Index
- About
- Usage
- The SVG file
- The data infotable
- Overrides in a nested infotable
- Overrides in a flat infotable
- Types of overrides
- Bindings and properties
- Installation
- Development
- Resources
- SVG Demo starter kit
- Installation
- Usage
- SVG Demo starter kit
- Gallery
- Credit/Acknowledgment
- License
About
This is a Thingworx widget allowing visualization of dynamic SVG files. It works by receiving an SVG file and an InfoTable dataset containing "overrides". Using this "overrides" you can modify the attributes of any SVG element to do stuff like changing colors, strings or even dimensions of an element. Additionally, it has features like dynamic pan and zoom and synchronized selection for more specific usecases.
Usage
It's highly recommended to use the starter kit if you want to use the widget. See more details about it here. For a simple example on how the widget works on its own, here is how to use the with a simple SVG file and a dataset:
1. The SVG file
The widget accepts any standard SVG file, either generated manually, via a Vector based tool like Adobe Illustrator, Corel Draw or Inkscape, or transformed from another format. For example, you can convert PDF or DWG schematics to SVG using online tools, and use that SVG in the widget.
To illustrate the features of the SVG widget, assume the following SVG file, where the elements that you want to update/interact with are clearly identifiable (via id or a custom attribute, like the tagName below)
Here is the SVG file in this example:
<svg width="100%" height="100%"
xmlns="http://www.w3.org/2000/svg">
<path fill="transparent" stroke="#000" stroke-width="1.5" d="m132.5,66.4375l-36.5,103.5625l62,-48l24,-45l-49.5,-10.5625z" identifier="myPath1"/>
<text fill="#000000" stroke="#000" stroke-width="0" x="133.5" y="159.4375" identifier="myText1" font-size="24" font-family="Helvetica, Arial, sans-serif" text-anchor="start">Text1</text>
<g identifier="myGroup2">
<line stroke-width="1.5" x1="358.5" y1="86.4375" x2="340.5" y2="172.4375"/>
<line stroke-width="1.5" x1="415.5" y1="180.4375" x2="336.5" y2="167.4375"/>
<line stroke-width="1.5" x1="366.5" y1="84.4375" x2="414.5" y2="170.4375"/>
<ellipse stroke-width="1.5" cx="396" cy="112.4375" rx="13.5" ry="16"/>
</g>
<rect fill="none" stroke-width="1.5" x="329.5" y="79.4375" width="94" height="110" stroke="#000" identifier="elementSelectable2"/>
<text fill="#000000" stroke="#000" stroke-width="0" x="348.5" y="216.4375" identifier="myText2" font-size="24" font-family="Helvetica, Arial, sans-serif" text-anchor="start">Text2</text>
<line fill="none" stroke="#000" stroke-width="1.5" x1="165.5" y1="107.4375" x2="330.5" y2="140.4375" identifier="myText3" class="test"/>
<path stroke="#000" stroke-width="1.5" d="m218.5,125.4375l5.5,-22.4375l16,18l-21.5,4.4375z" identifier="myPath4" otherIdentifier="selector1"/>
</svg>

This file contains 3 main "elements". The path with "Text1" written underneath it, a complex shape labeled "Text2" and a line between them.
The SVG file can be stored either in a FileRepository, as a MediaEntity, or, eternal to Thingworx, by adding a complete URI.
2. The data infotable
By default your SVG will be static, meaning that it will show up as designed. However you can change it's appearance by using an infotable that contains “overrides”.
There are two ways of declaring this overrides:
2.1. Overrides in a nested infotable
The best way to do it is to use a nested infotable for your overrides. By using a nested infotable, you can group together multiple elements in the SVG under the same row. A common usecase is when you want to have synchronized selection between multiple elements in the SVG and one element in a list/grid.
So, for the SVG above, this infotable can be:
| ElementGroup1 | AdditionnalMetadata | Overrides |
|---|---|---|
| MyElementGroup1 | Description of element | NestedInfotable1 |
| MyElementGroup2 | Description of element | NestedInfotable2 |
| MyElementGroup3 | Description of element | NestedInfotable3 |
Here, we have a simple infotable intended to be displayed both in a list and as the datasource for the SVG widget. When displayed on the list, only the 3 elements will appear. The SVG widget will use only the Overrides column.
- The
NestedInfotable1for the first row can be:
| elementName | elementSelector | text | stroke | fill | selectable |
|---|---|---|---|---|---|
| myPath1 | red | rbga(107,249,236,0.05) | TRUE | ||
| myText1 | New Text! | FALSE |
The first row means that the widget will search for an element that has the identifier attribute equal to myPath1, change the stroke attribute to red, the fill to rbga(107,249,236,0.05). You can add additional columns in your datashape, to override additional element attributes. Additionally, the element is marked as selectable meaning that it will be clickable and can drive synchronized selection.
The second row means that the contents of element with the identifier equal to myText1 will be changed to New Text!. This text element is not selectable, and we are not overriding any of the other attributes.
- The
NestedInfotable2for the second row can be:
| elementName | elementSelector | text | stroke | fill | selectable |
|---|---|---|---|---|---|
| myGroup2 | green | FALSE | |||
| myText2 | New Text2! | red | FALSE | ||
| elementSelectable2 | rbga(107,249,236,0.05) | TRUE |
Overrides in a flat infotable
If synchronized selection between an external list and the svg widget is not needed, you can also use a flat infotable for the overrides. However, you lose the capability to disable selection on some elements.
| elementName | AdditionalMetadata | override-fill | override-stroke | override-text |
|---|---|---|---|---|
| myPath1 | rbga(107,249,236,0.05) | red | ||
| myText1 | New Text! | |||
| myGroup2 | green | |||
| myText2 | red | New Text2! | ||
| elementSelectable2 | rbga(107,249,236,0.05) |
The only required column is ElementName. This column maps the override rows to the elements in the svg. For example, the infotable above will change the fill, stroke and override-text of all the elements in the group myPath1 to the values (rbga(107,249,236,0.05), red and _ respectively).
The elements in the infotable also dictate what elements are clickable.
2.2. Types of overrides
It's also important to note that the overrides for fill, stroke are just examples. You can override any attribute of the svg, including dimensions like width or height, position like x and y. However, there are a couple of special overrides that you can include:
tooltip: Specify a tooltip for an element. This is visible when hovering.text-stroke-width: If you override thestroke-widthof a group, you may find that thetextelements are hard to read. This is a special override for thestroke-widththat applies only totextelements.text: Change the contents of a<text>or<tspan>element. If a string is empty or undefined, it will not be updated. For specifying an empty value, use(a space).class: Class to add to the element. The exiting classes are not removed, but rather the new class is appended.selectable: Marks the element as clickable, meaning that it can drive the synchronized selection.
3. Bindings and properties
SVGFileUrl: Do not select a MediaEntity using the entity picker. A binding must be created. The SVG file can be stored either in a FileRepository, as a MediaEntity, or, eternal to Thingworx, by adding a complete URI.Data: An infotable containing the overrides for elements in the SVG. See the section above for information about the possible structures of this overrides tables. Keep in mind that synchronized selection is supported on this property.DataIdField: The column in your overrides infotable with the element to match. If using a nested override table, this column refers to the column inside a nested row.SVGIdField: the name of the attribute in the svg that maps with theDataIdField.DataSelectorField: The column in your overrides infotable containing a css selector to identify an element in the infotable. If this value is present on the override, then the element will be identified using the selector, and not using the combination ofDataIdFieldandSvgIdField.SelectedStyle: style of the selected elements. The style definition is applied as following:Background Color->fillattributeLine Color->strokeattributeLine Thickness->stroke-widthattribute- The rest of the properties in the style definition are ignored.
ApplyToChildren: This specifies whether to apply the overrides to the element or to its children recursively. Default istruebut, in most cases, you want thisfalse.ZoomPanEnabled: Enable zooming and and panning around the svg. Especially useful interaction is needed and the svg contains a schematic that is too big to represent. If it's enabled, than you can configure the initial zoom level or the position using theInitialXPosition,InitialYPositionandIntialZoomIf not, you can scale the SVG as you want.SelectedElementID: property available at runtime that is equal to the attribute of the current selected element.
The following events are also available:
ElementClicked,ElementDoubleClicked,ElementMiddleClicked. They are triggered after a named element has been clicked.
The following service is available:
PanOntoSelected: Pans onto the selected element, as to bring it into the center of the screen.ZoomPanEnabledmust be set to true for this to work.
4. Installation
- Navigate to the releases page
- Under the latest release, view all the assets
- Download the file
svgViewer-min-<VERSION>.zip - Import the widget into Thingworx
Development
This projects welcomes contributions. For details about pre-requisites, development environment and file structure, please see stefan-lacatus/ThingworxDemoWebpackWidget.
1. Build
The following commands allow you to build and compile your widget:
yarn run build: builds the extension. Creates a new extension zip file under thezipfolder.yarn run watch: watches the source files, and whenever they change, do a buildyarn run upload: creates a build, and uploads the extension zip to the thingworx server configured inpackage.json.
Resources
2. SVG Demo starter kit
Inside this repository, under /demo you can also find a Thingworx starter project that can help you get started with the widget. The demo is based on the WebDesignKit by Dumitru Zanfir

The goal of the demo is to provide a starting point for creating a ThingModel that easily ties in with the SvgWidget. So, we have a Network of Things, each implementing the SvgEnabledThingShape. Then, each thing, via the GetSvgOverrides service returns the specific overrides of that thing.
The prebuilt mashup, SvgVisualizationWebDesign, uses the SvgDataCollectorThing that collects data from all the things in a network with the SvgEnabledThingShape and generates a nested overrides Dataset.
2.1. Installation
- Install the WebDesignKit by Dumitru Zanfir
- Install the D3RangeChart Widget
- Install the SVG widget
- Import the demo/SvgStarterEntities.xml
- Import the demo/SvgCandyFactoryEntities.xml
- Upload the 3 svg files in demo to the
SvgFileRepository - View the
SvgVisualizationWebDesignmashup
2.2. Usage
- Upload your own SVG file into
SvgFileRepository - On your things, add the
SvgEnabledThingShape, and override the serviceGetSvgOverrides. Use the existing things as an example. - Modify the SvgFilesToDisplay property on
SvgDataCollectorThing. - Create a network with your things.
Gallery



Credit/Acknowledgment
Petrisor Lacatus ([email protected])
License
This Extension is provided as-is and without warranty or support. It is not part of the PTC product suite. ISC License