Widget

Common features of the WebStudio widgets.

Every widget needs to have a unique id. If the id is not set, WebStudio will generate one automatically. The assigned value can be adjusted as long it is unique.

Model

{
    "type": "widget type",
    "actions" : {},
    "captionBar": true,
    "dataSource" : {},
    "dragSource": {},
    "dropTarget": {},
    "id": "yLtC",
    "layout": {},
    "name": "NAME",
    "options": {
        "refreshInterval": 0
    },
    "toolbars": {}
}
Field Description

actions

The actions property is optional and can be used to implement action pipelines for selected trigger events

captionBar

Widget caption bars are shown by default. Set to false to hide the caption bar.

dataSource

Optional DataSource to load data and model settings from.

dragSource

Optional property to allow dragging from the widget

dropTarget

Optional property to handle drops from a dragSource

id

Unique widget identifier

layout

This property can be used to specify the size and position of the widget.

name

Will be shown in the caption bar if it is enabled.

options

Set the refreshInterval and styles for the widget. See the Options section for more detail.

toolbars

Optional configuration to add, customise or hide toolbars. Multiple toolbars can be configured for a single widget. See the Toolbars section below.

type

Widget type

Caption bar

All widgets have a caption bar, which is shown by default, but can be hidden by setting the captionBar property to false:

{
    "captionBar": false
}
With developer tools enabled, widget models can be accessed by clicking on the DevToolsBtn icon in the WebStudio toolbar. This will display the developer tools indicator on the right-hand side of the caption bar of a widget when hovering over the widget. If the caption bar of a widget is hidden, then the developer tools indicator will be shown in the top right-hand corner of the widget when hovering over it. Clicking on this indicator will open the Widget Model Editor for the selected widget.

If more control over the appearance of the caption bar is required, the composite version of the property can be used.

{
    "captionBar": {
        "hidden": false,
        "title": "Widget Title",
        "style": {
            "borderWidth": "1px",
            "borderStyle": "solid"
        },
        "styleByTheme": {
            "light": {
                "borderColor": "black"
            },
            "dark": {
                "borderColor": "white"
            }
        }
    }
}
Field Description

hidden

Set to false by default. The value can be changed at runtime, using a modify action for example, to show or hide caption bar. The same can be achieved by setting the captionBar property itself to the desired value, at the expense of losing the title value when showing the caption again.

title

Optional title string. If omitted, the title will be name or type when name is not defined.

style and styleByTheme

These properties are used to customize the appearance of the captionBar by setting CSS style values.

If the widget caption bar is hidden, the drag handle (=) can be accessed in the floating developer toolbar when the layout.static property is set to "false".

Drag Handle in Floating Developer Toolbar
Figure 1. Drag Handle in Floating Developer Toolbar

Toolbars

Widgets can be configured to have one or more custom toolbars on each side. Some widgets already have a default bottom and or top toolbar. These default toolbars can be extended, customized or overruled.

Custom tools

Define custom tools to be added to the toolbar and their actions.

Toolbar Scrolling

If there is not enough space to display all tools, then floating navigation arrows will be shown in the widget toolbar. These arrows can then be used to navigate to all tools on the toolbar.

Navigation Arrows for Toolbar Scroll

By default, each tool has opacity: 0.7 and opacity: 1.0 on hover, to match the look and hover effect of the default tools. The default behavior can be overruled by defining a different opacity in the style or styleByTheme of the tool definition.

Cascading Opacity

If the opacity is defined in the toolbar style property, then the opacity of tools in the toolbar will also be affected. For stacked elements, such as a tool on a toolbar, each with their own opacity values, the opacity of the topmost item is determined by multiplying the opacity values for the stacked objects.

{
  "toolbars": {
        "top": {
            "tools": {
                "addRow": {
                    "type": "button",
                    "icon": {
                        "icon": "🟢"
                    },
                    "style": {},
                    "styleByTheme": {},
                    "actions": {
                        "onClick": {
                            "type": "notify",
                            "text": "Custom tool clicked."
                        }
                    }
                }
            },
            "leftOrTop": {
                "toolsOrder": [
                    "addRow"
                ]
            }
        }
    }
}
Field Description

left, top, right, bottom

Defines where the toolbars should be located. Can be defined as an object (for a single toolbar), or an array (for multiple toolbars).

hidden

The complete toolbar can be hidden by setting this property to true.

tools

Contains the "named" tools to be added to the toolbar. In the example above, a single addRow button is defined. The name is used to set the display order in the toolsOrder field.

<tool name>

Define the appearance and actions for a tool. The name should be chosen to reflect its purpose.

type

Mandatory property to define the tool type. The supported tool types are button, chart-tool, diagrams-tool, input, label, selector, spacer and table-tool.

actions

Define tool custom actions to respond to. Currently the only action trigger available is onClick. By only specifying the type and the subType the tool will keep it’s default behavior specific to the widget.

{
    "toolbars": {
        "top": {
            "tools": {
                "addRow": {
                    "type" : "button",
                    "actions": {
                        "onClick": {
                            "type": "notify"
                        }
                    }
                }
            }
        }
    }
}

disabled

Can be used to disable a tool. The tool will still be visible in a disabled state and cannot be clicked.

dropTarget

This property can be used to define a drop target to support multiple drop behaviours within a single widget. This property is only supported for the label tool.

canDrop

Optional property containing a style and/or styleByTheme used to indicate that the label is a drop-target for the current drag topic. The style applies while the drag is in progress but the cursor is not over the label in the toolbar of the widget.

enabled

The drop target can be enabled by setting this property to true

hover

Optional property containing a style and/or styleByTheme used to indicate that the label is a drop-targer for the current drag topic. The style applies while the drag is in progress and the cursor is hovering over the label in the toolbar.

onDrop

This is used to define an action pipeline for processing the message object that is dropped onto the label.

topic

The label will only accept drop actions from drag sources with the same topic string.

hidden

A tool can be hidden by setting this property to true.

icon

Tool icon. Can be omitted if only the title is needed.

If an icon is used without a title, it only appears in the toolbar for the active theme when an icon resource matching that theme is provided. This will be the case when the icon property contains either a theme specific value (for light or dark) or a theme agnostic icon value. Otherwise the <tool name> will appear as a placeholder.

style

Optional styling to be applied.

styleByTheme

Optional theme specific styling.

subType

Can be used to use the icon and styling of a build-in tool and to link to a default action. If the tool action is not configured, the corresponding default widget behavior (if applicable) will be executed on click.

title

Optional tool text. Can be omitted if only an Icon should be displayed. It can also be defined as an object and custom styling can be provided with the style or styleByTheme properties.

tooltip

This property can be used to specify a custom tooltip for the tool, which will be displayed when hovering over the tool.

center

List of tool-names and/or toolGroup-names indicating which tools should be displayed in the center of the toolbar. Note : The tool or toolGroup name must appear somewhere in the toolsOrder field, otherwise, they will not be shown.

defaultTools

Define the configuration for the default tools in the top or bottom toolbars (if applicable). For now, this configuration only contains the hidden field.

hidden

Define whether the default tools should be shown (automatically). Setting this option to true will hide the default tools and allows them to be overruled by custom defined tools.

toolsOrder

Define the order in which the tools are displayed. For vertical toolbars, they are arranged top to bottom. For horizontal toolbars, they are arranged left to right.

leftOrTop

List of tool-names and or toolGroup-names indicating at which side of the toolbar they are drawn (left for horizontal toolbars or top for vertical toolbars). Note : The tool or group name must appear somewhere in the toolsOrder, otherwise they will not be shown.

defaultTools

Define the configuration for the default tools in the top toolbar (if applicable). For now, this configuration only contains the hidden field.

hidden

Define whether the default tools should be shown (automatically). By setting this option to true, the default tools will not be shown and can be overruled by custom defined tools.

toolsOrder

Define the order in which the tools are drawn. For vertical toolbars, they are arranged from top to bottom. For horizontal toolbars, they are arranged from left to right.

menu

Can define a context menu configuration when a "button" tool has the subType "menu". See the Custom Menu Tool section below for more details.

rightOrBottom

List of tool-names and or toolGroup-names indicating at which side of the toolbar they are drawn (right for horizontal toolbars or bottom for vertical toolbars). Note : The tool or group name must appear somewhere in the toolsOrder, otherwise they will not be shown.

defaultTools

Define the configuration for the default tools in the bottom toolbar (if applicable). For now, this configuration only contains the hidden field.

hidden

Define whether the default tools should be shown (automatically). By setting this option to true, the default tools will not be shown and can be overruled by custom defined tools.

toolsOrder

Define the order in which the tools are drawn. For vertical toolbars, they are arranged from bottom to top. For horizontal toolbars, they are arranged from right to left.

toolGroups

Contains the "named" tool groups to be added to the toolbar. The name is used to set the display order in the toolsOrder field. Can be used to group multiple "named" tools.

<group name>

Define the appearance for a tool group. The name should be chosen to reflect its purpose.

toolsOrder

Define the order in which the tools are drawn within the group. The order is the same for the leftOrTop and rightOrBottom configurations.

disabled

Can be used to disable a tool group. The tools within the group will be shown in a disabled state and cannot be clicked.

hidden

A tool group can be hidden by setting this property to true. The tools within the group will not be shown.

Tool icons

This section describes the tools by type and subtype

Type SubType Icon

button

compare

Compare Models Btn

button

copy

Copy Model Btn

button

date-picker

Date Picker Btn

button

delete

Delete Btn

button

export

Export Btn

button

filter

Filter Btn

button

format

JSON Format

button

import

Import Btn

button

new

New

button

panel-bottom

Panel Bottom Btn

button

panel-left

Panel Left Btn

button

panel-right

Panel Right Btn

button

refresh

Refresh Btn

button

save

Save Btn

button

search

Search Btn

button

settings

Settings Btn

button

split

Split Btn

button

submit

Submit Btn

chart-tool

clear-cursors

Clear Cursors

chart-tool

collapse-x-axis

Collapse Axis Btn

chart-tool

crosshair

Crosshair Btn

chart-tool

cursors-show-timestamp

Cursors Timestamp

chart-tool

edit-cursors
edit-pen
edit-x-axis
edit-y-axis

Edit Cursors

chart-tool

exit-edit-cursors
exit-edit-pen
exit-edit-x-axis
exit-edit-y-axis

Exit Edit Cursors

chart-tool

grab

Export Btn

chart-tool

group-x-axis

Group X Axis

chart-tool

historical-data-auto-refresh

Historical Data Auto Refresh Btn

chart-tool

historical-data-play

Historical Data Play Btn

chart-tool

historical-data-refresh

Refresh Btn

chart-tool

new-pen
new-x-axis
new-y-axis

Add Pen and Axes Btn

chart-tool

relative-x-axis

Relative X Axis Btn

chart-tool

stack-y-axis

Stack Y Axis Btn

chart-tool

unstack-y-axis

Unstack Y Axis

chart-tool

zoom-in

Zoom In Btn

chart-tool

zoom-out

Zoom Out Btn

diagrams-tool

open-iframe

Open IFrame Btn

diagrams-tool

open-new-window

Open New Window Btn

input

search

Search Input

input

time-period

Time Period

label

Label

menu

Menu Btn

selector

editor-language

Editor Language Menu

selector

report-design

Report Design Menu

spacer

table-tool

page-control

Page Control

table-tool

selected-rows-indicator

Selected Rows Indicator

table-tool

visible-rows-indicator

Visible Rows Indicator

Custom Menu Tool

The menu tool can be used to create a custom context menu popup. It is configured similarly to a widget toolbar but contains additional properties to configure the placement of the popup and the alignment of tools. It can also be defined in the WebStudio app bar.

{
    "toolbars": {
        "top": {
            "tools": {
                "context-menu": {
                    "type": "menu",
                    "menu": {
                        "tools": {
                            "tool01": {
                                "type": "button",
                                "subType": "refresh"
                            },
                            "tool02": {
                                "type": "button",
                                "subType": "save"
                            }
                        },
                        "leftOrTop": {
                            "toolsOrder": [
                                "tool01",
                                "tool02"
                            ]
                        },
                        "toolsAlignment": "vertical",
                        "placement": "right"
                    }
                }
            },
            "rightOrBottom": {
                "toolsOrder": [
                    "context-menu"
                ]
            }
        }
    }
}
Field Description

horizontalOffset

Defines the horizontal distance between the tool button origin and the menu popup placement point. Default is 0.

placement

Configure the placement of the menu popup when it is opened. The available options are left, right, top and bottom (default).

style

Optional property to define styling options for the menu popup window.

styleByTheme

Optional configuration for theme-specific styling of the menu popup window.

toolsAlignment

Configure the alignment of the tools in the menu popup. Can be horizontal or vertical.

verticalOffset

Defines the vertical distance between the tool button orgin and the menu popup placement point. Default is 0.

If a title or icon is defined for the menu tool, the default ellipsis icon MenuToolBtn will be overwritten.

Default and Custom Actions for Tools

Most widgets have tools with a default implementation. If tools are added to a widget toolbar with no default implementation or have no defined onClick action, they will be greyed out.

Tools with no Default Implementation

Using the perform-default-onClick action, tools with a default onClick implementation on a specific widget can support both default and custom actions within the same action pipeline. Actions are implemented in the order in which they are defined. In the following example, the default onClick action is invoked first followed by a custom action.

{
    "toolbars": {
        "tools": {
            "custom-tool": {
                "type": "button",
                "subType": "refresh",
                "actions": {
                    "onClick": [
                        {
                            "type": "perform-default-onClick"
                        },
                        {
                            "type": "notify"
                        }
                    ]
                }
            }
        }
    }
}

Drag-Drop

Widgets can be configured to serve as drag-sources and/or drop-targets, allowing data to be exchanged between them and pipeline actions to be triggered. The drag-drop functionality is internal to the WebStudio compilation and does not support dragging data from outside the view onto a widget or vice versa.

While all widgets support drag-drop some, like the tree widget, in addition support dragging data elements. Refer to the widget-type specific documentation for the details.

Configuring a drag source.

A widget can be made into a drag source by adding the following element to its model at root level:

{
    "dragSource": {
        "topic": "DragDropTopic-1",
        "enabled": true,
        "onDrag": {
            "action": {} // Action pipeline to initialize the message passed to the drop target
        },
        "dragPreview": {}
    }
}
Field Description

enabled

The drag source is enabled by default, but can be disabled by setting this property to false.

dragPreview

Optional property used to provide visual feedback of the content being dragged. If the value is not provided, the widget name is used. If no widget name is set, the widget type is the fallback.

The dragPreview has a type property, which determines what other fields can be configured. The supported types are:

  • "image": Shows a preview image. Refer to the image widget’s model for an explanation of the fields relating to this type.

    {
        "dragPreview": {
            "type": "image",
            "url": " https://www.inmation.com/hubfs/downloads/webstudio_image_frame.jpg",
            "style": { // Fix the size of the preview image
                "width": "100px",
                "height": "100px"
            }
        }
    }
  • "icon-label": Use a label and icon for the preview.

    {
        "dragPreview": {
                "type": "icon-label",
                "icon": {
                    "icon": "📦"
                },
                "label": {
                    "text": "Data",
                    "style": {
                        "fontFamily": "monospace"
                    }
                },
                "style": {
                    "fontSize": "30px"
                }
            }
    }
    • icon: Optional icon used in the drag preview. Refer to the icons section below for more details

    • label: Optional label, used to override the default text. Note that if the label is not provided, only the icon will be shown.

      • style and styleByTheme: Allow the text appearance to be tweaked without affecting the icon.

      • text: Preview text.

    • style and styleByTheme: The appearance of both the label and icon can be controlled using the outer style settings, which will be cascaded down to the inner elements.

If a fontSize is set in the outer style property, it will be applied to both the text and used to assign the width and height of the icon, unless explicit size properties are provided for the icon using the style settings in the icon property.

onDrag

Used, when the drag starts to initialize the message object that will be passed to the drop-target. This might involve collecting the widget data or extracting properties from the source widget’s model using a modify action, etc.

topic

Used to link the drag-source with one or more drop-targets. Widgets that have their dropTarget.topic properties set to the same value as that of the dragSource, will accept drops from that source.

Configuring a drop target

A widget can be configured as a drop-target by providing the following settings:

{
    "dropTarget": {
        "topic": "DragDropTopic-1",
        "canDrop": {
            "style": {}
        },
        "hover": {
            "style": {}
        },
        "enabled": true,
        "onDrop": {
            "action": {} // Action used to apply the provided data
        }
    }
}
Field Description

canDrop

Optional property containing a style and/or styleByTheme used to indicate that this widget is a drop-target for the current drag topic. The style applies while the drag is in progress, but the cursor is not over the widget.

enabled

The drop target is enabled by default, but can be disabled by setting this property to false.

hover

Optional property containing a style and/or styleByTheme used to indicate that this widget is a drop-target for the current drag topic. The style applies while the drag is in progress and the cursor is hovering over the widget.

onDrop

Used to define an action pipeline for processing the message object that is dropped onto the widget. This would typically involve using modify and transform actions to shape the data and apply it to the receiving widget’s work model.

topic

The widget accepts drop actions from drag-sources with the same topic string.

In addition, the label tool in the toolbars property can be defined as a drop target, allowing multiple drop behaviours within a single widget.

{
    "toolbars": {
        "top": {
            "tools": {
                "drop-target-label": {
                    "type": "label",
                    "dropTarget": {
                        "canDrop": {
                            "style": {}
                        },
                        "topic": "labelDragDrop",
                        "hover": {
                            "style": {}
                        },
                        "enabled": true,
                        "onDrop": {
                            "action": {}
                        }
                    }
                }
            },
            "leftOrTop": {
                "toolsOrder": {
                    "drop-target-label"
                }
            }
        }
    }
}

Drag drop examples

The first step when configuring drag-drop, is usually to decide:

  • From where to where the drag should be supported.

  • What data will be transported.

  • What visual feedback to provide to the users of the compilation.

To illustrate the point, let’s consider a very basic implementation in which we:

  • Drag from one text widget to another.

  • The data being exchanged is the text and the background color.

  • On drop, we want to apply the text from the source, and set the text color to the background color of the source.

The drag source for this example might be something like:

{
    "type": "text",
    "text": "Hello",
    "dragSource": { // Source widget from which we are dragging
        "topic": "TextDragDrop", // Topic name to link the source and target
        "dragPreview": { // Use a box emoji and label for the preview
            "type": "icon-label",
            "icon": {
                "icon": "📦"
            },
            "label": {
                "text": "DRAG TEXT"
            }
        },
        "onDrag": { // When the drag starts
            "action": {
                "type": "modify",
                "id": "self",
                "set": [
                    { //Copy the background color
                        "name": "payload.bg",
                        "value": "$model.options.style.backgroundColor"
                    },
                    { // and text to the message payload
                        "name": "payload.text",
                        "value": "$model.text"
                    }
                ]
            }
        }
    },
    "options": {
        "style": {
            "backgroundColor": "aquamarine"
        }
    }
}

The target widget config could be:

{
    "type": "text",
    "text": "Target",
    "captionBar": true,
    "dropTarget": {
        "topic": "TextDragDrop", // Match the topic with the source
        "canDrop": { // Set the border to indicate we accept this drop
            "style": {
                "border": "1px solid green",
                "backgroundColor": "transparent"
            }
        },
        "hover": { // Set the border to another color when we are over the widget
            "style": {
                "border": "1px solid yellow",
                "backgroundColor": "transparent"
            }
        },
        "onDrop": {
            "action": { // Apply the data from the message
                "type": "modify",
                "id": "self",
                "set": [
                    { // to set the text color
                        "name": "model.options.style.color",
                        "value": "$payload.bg"
                    },
                    { // and the text property
                        "name": "model.text",
                        "value": "$payload.text"
                    }
                ]
            }
        }
    },
    "options": {
        "style": {
            "color": "grey"
        }
    }
}

Let’s consider a second example, using the label tool as a drop target. In this case, we will drag source data from a text widget to a label on another text widget. For this, we will set up a drag source and a text widget with two labels as drop targets, each with their own behaviour:

  • Dropping the text from the source on the first label will change the text to the source text and set the background color of the widget to the color of the source text.

  • For the second label, on drop, the text will be updated to the source text and the text size will be increased.

The drag source for this example could be:

{
    "type": "text",
    "name": "Drag Source",
    "text": "Hello",
    "dragSource": {
        "topic": "dragDropLabels",  // must match the topic in the drop target
        "onDrag": {
            "action": {
                "type": "modify",
                "id": "self",
                "set": [
                    {  // copy the model text to the payload
                        "name": "payload.text",
                        "value": "$model.text"
                    },
                    { // copy the text color from the options property
                        "name": "payload.textColor",
                        "value": "$model.options.style.color"
                    },
                    { // assign a text size value that is greater than the default to field in payload
                        "name": "payload.textSize",
                        "value": "40px"
                    }
                ]
            }
        }
    },
    "options": {
        "style": {
            "color": "darkolivegreen"
        }
    },
    "id": "drag-source",
    "layout": {
        "x": 0,
        "y": 0,
        "w": 32,
        "h": 32,
        "static": false
    }
}

Then, the configuration of the text widget with the drop target labels could be:

{
    "type": "text",
    "name": "Label Drop Targets",
    "text": "Label Drop Targets",
    "toolbars": {
        "top": {
            "tools": {
                "label-drop-target-1": {
                    "type": "label",
                    "dropTarget": {
                        "canDrop": {
                            "style": {
                                "backgroundColor": "pink"
                            }
                        },
                        "topic": "dragDropLabels",  // must match the topic in the drag source
                        "onDrop": {
                            "action": {
                                "type": "modify",
                                "id": "self",
                                "set": [
                                    {  // set the model text
                                        "name": "model.text",
                                        "value": "$payload.text"
                                    },
                                    { // set the background color of the widget
                                        "name": "model.options.style.backgroundColor",
                                        "value": "$payload.textColor"
                                    }
                                ]
                            }
                        }
                    }
                },
                "label-drop-target-2": {
                    "type": "label",
                    "dropTarget": {
                        "canDrop": {
                            "style": {
                                "backgroundColor": "lightblue"
                            }
                        },
                        "topic": "dragDropLabels",  // must match the topic in the drag source
                        "onDrop": {
                            "action": {
                                "type": "modify",
                                "id": "self",
                                "set": [
                                    {  // set the model text
                                        "name": "model.text",
                                        "value": "$payload.text"
                                    },
                                    { // set the font size of the text
                                        "name": "model.options.style.fontSize",
                                        "value": "$payload.textSize"
                                    }
                                ]
                            }
                        }
                    }
                }
            },
            "leftOrTop": {
                "toolsOrder": [
                    "label-drop-target-1",
                    "label-drop-target-2"
                ]
            }
        }
    },
    "options": {
        "style": {
            "color": "grey"
        }
    },
    "id": "label-drop-target",
    "layout": {
        "x": 32,
        "w": 32,
        "h": 32,
        "y": 0,
        "static": false
    }
}

Also refer to the tree widget for details on how to use drag-drop from tree nodes. An example compilation can be found in the getting started section.

Layout

The layout property is used to specify where the widget appears in the compilation and how large it is. If layout is not provided, WebStudio will try to auto layout the widget.

The layout of a widget can be dynamically modified using a modify action. Using the modify action to change the layout preserves the current state of the widget. If changes to a widget’s layout do not impact the layout of any other widgets in the compilation, the changes will only be reflected in the work model. If modifying a widget’s layout causes changes to the layout of another widget, these changes will also be reflected in the initial model.
{
    "layout": {
        "x": 0,
        "w": 18,
        "h": 10,
        "y": 0,
        "static": false
    }
}
Field Description

x and y

Set the column and row position of the widget. (0, 0) denotes the top-left cell . Refer to the compilation numberOfColumns and numberOfRows options.

The x and y position values will be adjusted automatically by WebStudio to comply with the compilation options.stacking property.
The values for x and y must be integers.

w and h

Set the widget size expressed in the number of columns wide and number of rows high.
The values for w and h must be integers.

minW, maxW, minH, maxH

Bounds the size of the widget to the supplied numbers.
The values for minW, maxW, minH and maxH must be integers.

static

Setting the layout.static property to false, causes the move (=) and resize (⌟) drag handles to be hidden.

With the floating developer tools enabled, these tools can still be accessed when hovering over the widget.

Icons

While not all widgets make use of icons a number of them, such as the tree, table and tabs widgets, do. Where they can be configure, the model is common and supports simple emoji characters as well as bit-mapped and vector based graphics resources.

The icon model is shown below:

{
    "icon" : {
        "icon" : {},
        "dark" : {},
        "light": {},
        "alignment" : "leading",
        "style": {},
        "styleByTheme": {}
    },
}
Field Description

alignment

Icons are typically used together with a text label of some sort. The alignment property is used to indicate which side of the text the icons should be drawn on. Options are:

  • leading: The icon is shown in front of the associated text

  • trailing: The icon is shown after the text.

  • centerTop and centerBottom: where available allow the icon to be shown above or below the accompanying text.

icon

At first glance, it seems confusion to have an icon field inside the icon property, but considered with the other fields, light and dark it simply indicates the default resource to use when no explicit light or dark theme config is provided.

The inner icon, dark and light properties can either be assigned an emoji character:

{
    "icon" : "✅"
}

or a custom graphics element using the fields shown below:

base64

Base64 encoded image resource. If you are starting from a source image file, there are various online sites which can help to encode them.

mimeType

Provide a mime type consistent with the image specified in the base64 property. Refer to the image widget for more details in this regard.

url

Url for an online icon resource. For example:

{
    "icon" : {
        "dark" : {
            "url": "https://cdn3.iconfinder.com/data/icons/object-emoji/50/Lightbulb-256.png"
        }
    }
}

Many of the icons used in DataStudio are also available as local assets. They can be referenced using a url of the form:

"./assets/model/classes/<CLASSNAME>.svg"

The <CLASSNAME> can be found in name column of the Classes online documentation. for example:

{
    "icon" : {
        "dark" : {
            "url": "./assets/model/classes/ActionItem.svg"
        }
    }
}

light and dark

Icon to use with the light and dark themes.

style and styleByTheme

These properties are not always present where icons can be defined. Where present they are typically used to set the borders, background and size of the icon.

The following points should be considered when using graphics resources:

  • Icon width and height: Icons often appear along side accompanying text or labels. Where this is the case, the font-size of the text is used for the icon width and height. Where specific widget models permit the icon style to be configured, its size can be overridden using either css width and height properties or by specifying a fontSize.

  • Image data size: While the data size of images is not the big concern it once was, working with long base64 encoded strings in the compilations can be a hassle. It is therefor recommended that binary images be "compressed" before encoding them.

  • SVG Fill: When using monochrome SVG resources, fill styling can be omitted to allow the Widget to apply the current theme’s fill-colour, which alleviates the need to explicitly provide light and dark themed icons.

    Consider the following sample SVG images which defines a rectangle. If this source is encoded to base64 and used as an icon, the image will always be drawn in black and will be incapable of adjusting to the selected theme.

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <svg
       version="1.1"
       x="0px" y="0px" viewBox="0 0 350 350"
       style="enable-background:new 0 0 350 350;"
       xml:space="preserve"
       xmlns="http://www.w3.org/2000/svg"
       xmlns:svg="http://www.w3.org/2000/svg">
    <rect
       style="fill:#000000"
       width="257" height="246" x="44" y="46" />
     </svg>

    By simply removing the style="fill:#000000" attribute, the hosting widget can provide its own settings, allowing the same image to adjust automatically to both light and dark themes.

  • Icon color: As noted above, the color of monochrome SVG resources is set automatically based on the active theme. If the icon is used with associated text, such as in the case of a tree node or tool-bar button, the icon color will be overridden to match the font color assigned in the style/styleByTheme property of the text

Options

{
    "options": {
        "refreshInterval": 10,
        "style": {
            "backgroundColor": "transparent",
            "border": "1px solid blue"
        },
        "styleByTheme" : {
            "light" : {},
            "dark" : {}
        }
    }
}
  • refreshInterval: Lets the widget automatically refresh. Value is given in seconds. Minimum value is 0.5 seconds. The value 0 means that the refresh interval is disabled.

  • style: Every widget can be styled by setting the style object. The style object accepts a wide range of CSS styles. The CSS properties are only accepted in camelCase as can be seen from the example above.

    Some other border examples:

    • none

    • 1px dashed red

    • 1px dotted white

    • 4px double grey

    • 5px ridge white

    • 3px solid blue

    See more over here CSS Borders.

  • styleByTheme: Anywhere a style option is available in the widget model there will also be a styleByTheme property which, as the name suggests, provides a means to define theme specific styling. This is particularly useful for color settings, which often need to be matched to the theme.

    It is not mandatory to specify a style for both themes.

    Specifying both shorthand and non-shorthand options for the same value in the styleByTheme property can lead to conflicting behaviour when switching between themes. This can be avoided by replacing shorthand properties with the complete set of non-shorthand properties. For example, the shorthand property "borderWidth" can be replaced with the set of non-shorthand properties "borderBottomWidth", "borderTopWidth", "borderRightWidth" and "borderLeftWidth".

    If the options defined in the styleByTheme property are the same for the both light and dark themes, then using both shorthand and non-shorthand options will not cause conflicting behaviour when switching themes.

    The style and styleByTheme settings can be used together, the latter taking precedence when both define the same style attributes.

Action Pipeline

The widgets can perform logic in the form of actions. This can be a single action or a sequence of actions which we call an action pipeline. The data which is passed to and from one action to the other is called a message.

Actions can be defined within the actions field and in specific parts in the model. This is documented per widget type.

Performing multiple pipelines in parallel can be achieved by defining multiple arrays on the pipeline field.

Message Flow

The input message of a pipeline action contains:

{
    "topic": "", // Could be provided by the widget.
    "payload": {} // Typically an object.
}

The payload can be any type. Keep in mind that in order to be able merged with the input message it needs to be an object. The topic tells the executing / receiving widget what to do with the payload.

In case the output of an action doesn’t return an object with topic or a payload the output will be set to the input message payload of the next action.

With the next example only the payload is provided to the action.

{
    "type": "ACTION_TYPE"
}

In order to merge additional fields into the payload a pipeline action can be defined like:

{
    "type": "ACTION_TYPE",
    "message": {
        "payload": {
            "additionalValue": 42
        }
    }
}

In order to merge additional fields into the message a pipeline action can be defined like:

{
    "type": "ACTION_TYPE",
    "message": {
        "payload": {
            "additionalValue": 42
        },
        "additionalField": "Hello"
    }
}

Skip an action step

If you want to skip an action step during testing you can set the skip field to true.

DataSource

Data sources can be defined in the widget model to fetch data from and write data to the system. It can also be an action pipeline. The data returned from a dataSource is typically applied to the data field of the widget.

DataSource Pipeline

The dataSource can also be used to retrieve model elements from the backend allowing widgets to be dynamically customized at runtime. Depending on the type and content, data returned from a dataSource is interpreted by widgets as follows:

  • Array: The array is assumed to be data and is applied to the widget’s data property (if it has one)

  • Object: The object is inspected, looking for a property called type.

    • type matches the widget’s type: each top-level property in the returned data-set is applied to the corresponding widget property. For example, suppose the dataSource on a table widget returned the JSON shown below. The data, schema and options settings are overwritten in the work-model. There are however some important exceptions:

      {
          "payload": {
              "type": "table",
              "data": [
                  {
                      "name": "Inside Temperature",
                      "value": 26,
                  },
                  // ...
              ],
              "schema": [
                  {
                      "name": "name",
                      "title": "Name-NEW"
                  },
                  // ...
              ],
              "options": {
                  "multi": true
              },
              "actions": {
                  "onSubmit": {
                      // ... Submit action
                  }
              }
          }
      }
      • actions: The property is merged with the current model, which is to say, existing matching named actions are overwritten and new ones are added. Actions present in the model but not in the returned data are retained. If the table widget in our example already contained says onSubmit and didUpdate, then the onSubmit action would get overwritten, but the didUpdate will remain unchanged. By contrast any existing option settings not in the returned data-set are effectively lost.

      • id: The widget id cannot be changed by the dataSource and is ignored.

      • Other: There may be further merge behavior specific to individual widgets. Refer the relevant pages for these.

    • type not provided, or does not match the widget’s type: In this scenario, the update logic looks for specific properties in the message payload. These properties are widget-specific so more details can be found on each individual widget page.

Common actions:

  • function: Invokes an Advanced Endpoint.

  • read: Reads the dynamic value or a property value of an object.

  • read-write: Reads and writes the dynamic value or a property value of an object.

  • subscribe : Subscribes to the OnDataChanged event of a dynamic value.

  • write: Writes the dynamic value or a property value of an object.

Typically a dataSource has a single action.

{
    "dataSource": {
        "type": "read",
        "path": "/System/Core/Examples/Variable"
    }
}

In order to transform the output message of the read action, an action pipeline can be defined.

{
    "dataSource": [
        {
            "type": "read",
            "path": "/System/Core/Examples/Variable"
        },
        {
            "type": "transform",
            "aggregateOne": [] // See transform docs.
        }
    ]
}

Function

To invoke an Advanced Endpoint. The payload in the output contains the data returned by the Advanced Endpoint.

{
    "dataSource": {
        "type": "function",
        "lib": "LIBRARY NAME",
        "func": "FUNCTION NAME", // Optional function name in case library is Lua table.
        "farg": {}, // Optional function argument.
        "ctx": "" // Optional system object path.
    }
}

Read

Reads the dynamic value of an object or the value of an object property. The payload in the output contains the dynamic or property value.

{
    "dataSource": {
        "type": "read",
        "path": "/System/Core/Examples/Demo Data/Process Data/FC4711"
    }
}

Read-Write (*)

Reads and writes the dynamic value of an object or the value of an object property.

{
    "dataSource": {
        "type": "read-write",
        "path": "/System/Core/Examples/Demo Data/Process Data/FC4711"
    }
}

Subscribe

Subscribes to the OnDataChanged event of a dynamic value. The payload in the output contains the dynamic value.

{
    "dataSource": {
        "type": "subscribe",
        "path": "/System/Core/Examples/Demo Data/Process Data/FC4711"
    }
}

Actions

The actions is an object, the fields for which are known hooks, like the Life Cycle Hooks, or custom action names. Each element’s value can be a single action object or an array with actions in a pipeline.

{
    "actions": {}
}

Life Cycle Hooks

Widgets supports life cycle hooks. During loading, updating and refreshing many hooks are invoked. Hooks can contain any number of pipeline actions.

Overview of all the general hooks:

  • didLoad: Widget loaded on screen.

  • willUpdate: Widget will update view.

  • didUpdate: Widget did update view.

  • willRefresh: Widget will perform a refresh.

  • didRefresh: Widget did perform a refresh.

  • willFetch: Widget will perform a fetch.

  • didFetch: Widget did perform a fetch.

The hooks willFetch and didFetch are only invoked if the widget has a data source defined. Note that some widgets have root properties, like path on a Faceplate widget, which are considered as a data source.

Load Life Cycle Hooks

The load life cycle flow is:

  1. didLoad

  2. willFetch
    Execution of the data source action (pipeline)

  3. didFetch

  4. willUpdate
    Screen updated

  5. didUpdate

Refresh Life Cycle Hooks

The refresh life cycle flow is:

  1. willRefresh

  2. willFetch
    Execution of the data source action (pipeline)

  3. didFetch

  4. willUpdate
    Screen updated

  5. didUpdate

  6. didRefresh

Refresh can be executed by e.g. a refresh button, refresh interval and send action.

Update Life Cycle Hooks

The update life cycle flow is:

  1. willUpdate
    Screen updated

  2. didUpdate