Create a Data-Aware Item using an External Visualization Widget

  • 7 minutes to read

All custom items are based on the Web Dashboard's customization using independent modules called extensions. Learn about extension concepts by referring to the Extensions Overview topic.

This tutorial shows you how to create a more "real-world" custom item that uses an external visualization widget. In this example, it is the dxFunnel widget that can show values across multiple stages in a process. This widget supports data binding, master filtering, and coloring.

View Example: Create a Data-Aware Item using an External Visualization Widget


Before you begin, open the project created from the template. Then, follow the instructions below:

Create the Custom Item's Script File

In your project, add the FunnelChartItem.js file to the Custom_Items folder. Specify the script file URL in the <body> section to include scripts after the control is rendered:

 <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
    <script type="text/javascript">
        function onBeforeRender(sender) {
    <dx:ASPxDashboard ID="ASPxDashboard1" runat="server" Width="100%" Height="100%">
        <ClientSideEvents BeforeRender="onBeforeRender" />
    <script src="Custom_Items/FunnelChartItem.js"></script>

Provide a Toolbox Icon

Encapsulate a custom item in the IIFE function expression to prevent a name conflict a name conflict with custom items. Then, place an SVG icon into this function. The icon appears in the Custom Items Toolbox group.

var FunnelChartItem = (function () {
    var Dashboard = DevExpress.Dashboard;
    var Model = DevExpress.Dashboard.Model;
    var Designer = DevExpress.Dashboard.Designer;
    var dxFunnel = DevExpress.viz.dxFunnel;

    var svgIcon = '<svg id="funnelChartItemIcon" viewBox="0 0 24 24"><path stroke="#ffffff" fill="#f442ae" d="M12 2 L2 22 L22 22 Z" /></svg>';


The icon's identifier (svgIcon) is used later in this tutorial to initialize a custom item.

Specify the Custom Item's Settings

In the FunnelChartItem.js file, specify the custom item's metadata (ICustomItemMetaData) by adding following options:

  • The bindings option allows you to configure a set of dimensions/measures used to bind a custom item to data. The Funnel Chart dashboard item has one measure and one dimension in the Binding menu. Data to be displayed is obtained later using the iterateData method.
  • The customProperties option specifies the name, type, default value and owner of custom properties that are saved into the dashboard XML. These properties allow users to configure specific settings. For the Funnel Chart item, users can change a label's position.
  • The optionsPanelSections option specifies names of sections, type and editors' options that are displayed for each custom property in the Dashboard Designer.
  • The icon option allows you to pass the icon's identifier specified in the first step (funnelChartItemIcon).
  • The title option specifies the default custom item name.
var FunnelChartItem = (function () {
         // ...
    var funnelChartItemMetaData = {
        bindings: [{
            propertyName: 'measureValue',
            dataItemType: 'Measure',
            displayName: 'Value'
        }, {
            propertyName: 'dimensionValue',
            dataItemType: 'Dimension',
            displayName: 'Argument',
            enableColoring: true,
            enableInteractivity: true
        interactivity: {
            filter: true
        customProperties: [{
            ownerType: Model.CustomItem,
            propertyName: 'labelPositionProperty',
            valueType: 'string',
            defaultValue: 'Inside'
        optionsPanelSections: [{
            title: 'Labels',
            items: [{
                dataField: 'labelPositionProperty',
                label: {
                    text: 'Label Position'
                template: Designer.FormItemTemplates.buttonGroup,
                editorOptions: { 
                    items: [{ text: 'Inside' }, { text: 'Outside' }] 
        icon: 'funnelChartItemIcon',
        title: 'Funnel Chart',
        index: 2


Implement the Custom Item's Rendering

The CustomItemViewer class allows you to implement a visual representation of the custom item. You need to override the renderContent method to visualize dimension names as HTML content.

Create methods that allow you to display measure and dimension values from a data source and implement logic for a custom property:

  • The _getDataSource method returns data that is displayed in the custom item. Use the getDisplayText method to get dimension / measure names and the iterateData method to generate data rows for the custom item. The iterateData method accepts a function as a parameter and allows you to iterate through aggregated data and obtain required values (dimension or measure values, display texts, colors, etc.). The FunnelD3 item has one dimension whose values can be colored (the bindings | enableColoring option in the previous step). When an end-user binds the custom item to the data field and enables coloring, the iterateData method is called for each row in the aggregated data.
  • The _getDxFunnelWidgetSettings method is used to return widget's settings when you render custom item's content.

Override the following methods to support Master-Filtering and change the Funnel Chart's content size when you scale the dashboard:

  • The setSelection(values), clearSelection, and setMasterFilter methods are used to describe a custom item's behavior when you filter data by selecting an item's data rows.
  • The setSize(width, height) method allows you to scale the custom item when you change the item's size. This method should specify the correct widget size at runtime when the actual size is not known beforehand (svg-widgets).
var FunnelChartItem = (function () {
     // ...
        function FunnelChartItemViewer(model, $container, options) {
        var parent =, model, $container, options);

        this.dxFunnelWidget = null;
        this.dxFunnelWidgetSettings = undefined;
    FunnelChartItemViewer.prototype = Object.create(Dashboard.CustomItemViewer.prototype);
    FunnelChartItemViewer.prototype.constructor = FunnelChartItemViewer;

    FunnelChartItemViewer.prototype._getDataSource = function () {
        var clientData = [];
        if (this.getBindingValue('measureValue').length > 0) {
            this.iterateData(function (dataRow) {
                    measureValue: dataRow.getValue('measureValue')[0],
                    dimensionValue: dataRow.getValue('dimensionValue')[0] || '',
                    dimensionDisplayText: dataRow.getDisplayText('dimensionValue')[0],
                    measureDisplayText: dataRow.getDisplayText('measureValue')[0],
                    dimensionColor: dataRow.getColor('dimensionValue')[0],
                    clientDataRow: dataRow
        return clientData;

    FunnelChartItemViewer.prototype._getDxFunnelWidgetSettings = function () {
        var _this = this;
        return {
            dataSource: this._getDataSource(),
            argumentField: "dimensionValue",
            valueField: "measureValue",
            colorField: "dimensionColor",
            selectionMode: "multiple",
            label: {
                customizeText: function (e) {
                    return + ': ' +;
                position: this.getPropertyValue('labelPositionProperty').toLowerCase()
            onItemClick: function (e) {

    FunnelChartItemViewer.prototype.setSelection = function () {
        var _this = this;
        this.dxFunnelWidget.getAllItems().forEach(function (item) {

    FunnelChartItemViewer.prototype.clearSelection = function () {

    FunnelChartItemViewer.prototype.setSize = function (width, height) {
        Object.getPrototypeOf(FunnelChartItemViewer.prototype), width, height);

    FunnelChartItemViewer.prototype.renderContent = function ($element, changeExisting) {
        if (!changeExisting) {
            var element = $element.jquery ? $element[0] : $element;


            var div = document.createElement('div');
            this.dxFunnelWidget = new dxFunnel(div, this._getDxFunnelWidgetSettings());
        } else {


Register the Custom Item as an Extension

Create the funnelChartItem function that implements the ICustomItemExtension interface. This function is used to register the created custom item as the Web Dashboard's extension.

var FunnelChartItem = (function () {
     // ...
    function FunnelChartItem(dashboardControl) {
        Dashboard.ResourceManager.registerIcon(svgIcon); = "funnelChartCustomItem",
        this.metaData = funnelChartItemMetaData,
        this.createViewerItem = function (model, $element, content) {
            return new FunnelChartItemViewer(model, $element, content);

    return FunnelChartItem;

Go to the page containing the Web Dashboard code and pass the created function as the DashboardControl.registerExtension method's parameter. The dashboardControl variable is the DashboardControl instance:

function onBeforeRender(sender) {        
    // ...    
 function onBeforeRender(sender) {
        // The dashboardControl variable is the DashboardControl instance.
        dashboardControl.registerExtension(new FunnelChartItem(dashboardControl));

Refer to the following topics on how to obtain the DashboardControl:

Run the Project to See the Result

Run the project and click the Funnel Chart Toolbox item to add the custom item to the dashboard:


This adds the empty item to the dashboard.


Invoke the Binding menu, click Set Value in the Value section and select the required field. Then, click Set Argument to provide argument values:


Use Options | Coloring to enable coloring:


Add another dashboard item (for instance, the previously created Data-Aware Item) and bind it to data. Enable master filtering in the Funnel Chart and select any element to see the result:


You can change the labels position using the Options | Labels | Label Position custom option.