Skip to content

Developer Guide: Widget customization on Insights

Martin Peeters edited this page Nov 27, 2023 · 10 revisions

Manager UI

The Insights page allows you to create multiple dashboards within the Manager UI.
Using widgets you are able to customize what data to visualize, and how it should appear on the dashboard.
Currently we have several built-in widgets available:

Widget Description
image Chart with history and/or predicted data of unlimited attributes.
Uses data decimation algorithms, and supports multi-axis.
image Measuring instrument to compare the current value of an attribute with some predefined thresholds.
image Background image with attribute value labels that can be placed anywhere.
image Displays the current value of an attribute, and shows the trend in a chart.
image Map with locations of all assets that correspond with the selected asset type.
Optionally it can show a color based on thresholds, or a label with the current value of an attribute.

We might add more widgets over time, so this list can become longer.
Feel free to develop new widgets yourself; there is functionality to create them with ease.

Building custom widgets

The widget architecture is structured to support the additions of custom widgets, whereof a short tutorial is shown below.
To know more about the dashboard builder and it's terminology, check the README of the or-dashboard-builder component.

Creating your own Widget

Add your widget manifest to the registerWidgetTypes() function in index.ts.
This will register the widget, and handle all functions automatically.

export function registerWidgetTypes() {
    widgetTypes.set("linechart", ChartWidget.getManifest());
    widgetTypes.set("gauge", GaugeWidget.getManifest());
    ...
    // add here
}

From there, you can add your custom class to the /widgets folder and build your HTMLElements.
It is required to inherit from or-widget, (or an extended class of it such as or-asset-widget)
and your custom config should extend on WidgetConfig

Example of a custom Widget

Here is a code example of how to create custom widgets.
Feel free to copy, put it in seperate files, and adjust it to your needs.
Looking into our existing widgets also helps understanding the codebase.

export interface CustomWidgetConfig extends WidgetConfig {
    attributeRefs: AttributeRef[];
    customFieldOne: string;
    customFieldTwo: number;
}

function getDefaultWidgetConfig(): CustomWidgetConfig {
    return {
        attributeRefs: [],
        customFieldOne: "default text",
        customFieldTwo: 0
    };
}

@customElement("custom-widget")
export class CustomWidget extends OrWidget {

    // Override of widgetConfig with extended type
    protected readonly widgetConfig!: CustomWidgetConfig;

    static getManifest(): WidgetManifest {
        return {
            displayName: "Custom widget", // name to display in widget browser
            displayIcon: "gauge", // icon to display in widget browser. Uses <or-icon> and https://materialdesignicons.com
            minColumnWidth: 1,
            minColumnHeight: 1,
            getContentHtml(config: CustomWidgetConfig): OrWidget {
                return new CustomWidget(config);
            },
            getSettingsHtml(config: CustomWidgetConfig): WidgetSettings {
                return new CustomSettings(config);
            },
            getDefaultConfig(): CustomWidgetConfig {
                return getDefaultWidgetConfig();
            }
        }
    }

    public refreshContent(force: boolean) {
        // function that executes on refresh of the widget.
        // It's normally a 'silent' function that, for example, fetches the data of assets again.
    }

    protected render(): TemplateResult {
        return html`
            <span>Custom field one: </span>
            <span>${this.widgetConfig.customFieldOne}</span>
        `;
    }

}

// Settings element
// This can be placed in a seperate file if preferred.
@customElement("custom-settings")
export class CustomSettings extends WidgetSettings {

    // Override of widgetConfig with extended type
    protected readonly widgetConfig!: CustomWidgetConfig;

    protected render(): TemplateResult {
        return html`
            <span>Custom settings</span>
            <button @click="${() => this.onButtonClick()}">Click to customize text</button>
        `;
    }

    protected onButtonClick() {
        this.widgetConfig.customFieldOne = "custom text";
        this.notifyConfigUpdate();
    }
}

Clone this wiki locally