The example contains the source code of the scripts created in the step-by-step Custom Item tutorials.
Files to Review
Static Custom Item
View Tutorial: Create a Static Custom Item
View Script: HelloWorldItem.js
The script contains a HelloWorld static custom item with a custom property that allows you to change the static text.
Data-Aware Custom Item
View Tutorial: Create a Data-Aware Custom Item
View Script: DataAwareItem.js
This script contains a data-aware custom item that displays formatted dimension values and allows users to color these values.
Data-Aware Item based on External Visualization Widget
View Tutorial: Create a Data-Aware Item based on an External Visualization Widget
View Script: FunnelChartItem.js
This script contains 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.
Documentation
More Examples
- Dashboard for ASP.NET Core - Custom Item Gallery
- Dashboard for ASP.NET Core - Custom Properties
- Dashboard for React - Custom Item Tutorials
Example Code
JavaScriptwindow.HelloWorldCustomItem = (function () {
// #region svgIcon
const svgIcon = '<svg id="helloWorldItemIcon" viewBox="0 0 24 24"><path stroke="#42f48f" fill="#42f48f" d="M12 2 L2 22 L22 22 Z" /></svg>';
// #endregion
// #region metadata
const helloWorldItemMetaData = {
customProperties: [{
ownerType: DevExpress.Dashboard.Model.CustomItem,
propertyName: 'customProperty',
valueType: 'string',
defaultValue: 'Hello World!'
}],
optionsPanelSections: [{
title: 'Custom Properties',
items: [{
dataField: 'customProperty',
label: {
text: 'Item Text'
},
editorType: 'dxTextBox',
editorOptions: {
placeholder: "Enter text to display"
}
}]
}],
icon: 'helloWorldItemIcon',
title: 'Hello World Item'
};
// #endregion
// #region viewer
class HelloWorldItemViewer extends DevExpress.Dashboard.CustomItemViewer {
constructor(model, $container, options) {
super(model, $container, options);
}
renderContent = function ($element, changeExisting) {
var element = $element.jquery ? $element[0] : $element;
element.innerText = this.getPropertyValue('customProperty');
}
}
// #endregion
// #region createItem
class HelloWorldItem {
constructor(dashboardControl) {
DevExpress.Dashboard.ResourceManager.registerIcon(svgIcon);
this.name = "helloWorldItem";
this.metaData = helloWorldItemMetaData;
}
createViewerItem(model, $element, content) {
return new HelloWorldItemViewer(model, $element, content);
}
}
return HelloWorldItem;
// #endregion
})();
JavaScriptwindow.DataAwareCustomItem = (function () {
// #region svgIcon
const svgIcon = '<svg id="dataAwareItemIcon" viewBox="0 0 24 24"><path stroke="#ffffff" fill="#4842f4" d="M12 2 L2 22 L22 22 Z" /></svg>';
// #endregion
// #region metadata
const dataAwareItemMetaData = {
bindings: [{
propertyName: 'dimensionValue',
dataItemType: 'Dimension',
displayName: 'Dimension',
enableColoring: true
}],
customProperties: [{
owner: DevExpress.Dashboard.Model.CustomItem,
propertyName: 'backColorProperty',
valueType: 'string',
defaultValue: 'None'
}],
optionsPanelSections: [{
title: 'Background',
items: [{
dataField: 'backColorProperty',
label: { text: 'Backcolor' },
template: DevExpress.Dashboard.Designer.FormItemTemplates.buttonGroup,
editorOptions: {
items: [{ text: 'None' }, { text: 'Red' }, { text: 'Blue' }]
}
}]
}],
icon: 'dataAwareItemIcon',
title: 'Data Aware Item'
};
// #endregion
// #region viewer
class DataAwareItemViewer extends DevExpress.Dashboard.CustomItemViewer {
constructor(model, $container, options) {
super(model, $container, options);
}
renderContent($element, changeExisting) {
var element = $element.jquery ? $element[0] : $element;
while (element.firstChild)
element.removeChild(element.firstChild);
var clientData = this._getDataSource();
clientData.forEach(function (item) {
var div = document.createElement('div');
div.style.color = item.color;
div.innerText = item.dimensionDisplayText;
element.appendChild(div);
});
element.style.background = this._getBackColorProperty();
}
_getDataSource() {
var clientData = [];
this.iterateData(function (dataRow) {
clientData.push({
dimensionDisplayText: dataRow.getDisplayText('dimensionValue')[0] || "",
color: dataRow.getColor()[0]
});
});
return clientData;
}
_getBackColorProperty() {
switch (this.getPropertyValue('backColorProperty')) {
case 'None': return "rgb(255,255,255)";
case 'Red': return "rgb(255,220,200)";
case 'Blue': return "rgb(135,206,235)";
}
}
}
// #endregion
// #region createItem
class DataAwareItem {
constructor(dashboardControl) {
DevExpress.Dashboard.ResourceManager.registerIcon(svgIcon);
this.name = "dataAwareItem";
this.metaData = dataAwareItemMetaData;
}
createViewerItem(model, $element, content) {
return new DataAwareItemViewer(model, $element, content);
}
}
return DataAwareItem;
// #endregion
})();
JavaScriptwindow.FunnelChartCustomItem = (function () {
// #region constMetadata
const Model = DevExpress.Dashboard.Model;
const Designer = DevExpress.Dashboard.Designer;
// #endregion
const Dashboard = DevExpress.Dashboard;
const dxFunnel = DevExpress.viz.dxFunnel;
// #region svgIcon
const svgIcon = '<svg id="funnelChartItemIcon" viewBox="0 0 24 24"><path stroke="#ffffff" fill="#f442ae" d="M12 2 L2 22 L22 22 Z" /></svg>';
// #endregion
// #region metadata
const 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'
};
// #endregion
// #region viewer
class FunnelChartItemViewer extends Dashboard.CustomItemViewer {
constructor(model, $container, options) {
super(model, $container, options);
this.dxFunnelWidget = null;
this.dxFunnelWidgetSettings = undefined;
}
_getDataSource() {
var clientData = [];
if (this.getBindingValue('measureValue').length > 0) {
this.iterateData(function (dataRow) {
clientData.push({
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;
}
_getDxFunnelWidgetSettings() {
var _this = this;
return {
dataSource: this._getDataSource(),
argumentField: "dimensionValue",
valueField: "measureValue",
colorField: "dimensionColor",
selectionMode: "multiple",
label: {
customizeText: function (e) {
return e.item.data.dimensionDisplayText + ': ' + e.item.data.measureDisplayText;
},
position: this.getPropertyValue('labelPositionProperty').toLowerCase()
},
onItemClick: function (e) {
_this.setMasterFilter(e.item.data.clientDataRow);
}
};
}
setSelection() {
var _this = this;
this.dxFunnelWidget.getAllItems().forEach(function (item) {
item.select(_this.isSelected(item.data.clientDataRow));
});
}
clearSelection() {
this.dxFunnelWidget.clearSelection();
}
setSize(width, height) {
super.setSize(width, height);
this.dxFunnelWidget.render();
}
allowExportSingleItem() {
return true;
}
renderContent($element, changeExisting) {
if (!changeExisting) {
var element = $element.jquery ? $element[0] : $element;
while (element.firstChild)
element.removeChild(element.firstChild);
var div = document.createElement('div');
div.style.width = "100%";
div.style.height = "100%";
element.appendChild(div);
this.dxFunnelWidget = new dxFunnel(div, this._getDxFunnelWidgetSettings());
} else {
this.dxFunnelWidget.option(this._getDxFunnelWidgetSettings());
}
}
}
// #endregion
// #region createItem
class FunnelChartItem {
constructor(dashboardControl) {
Dashboard.ResourceManager.registerIcon(svgIcon);
this.name = "funnelChartCustomItem",
this.metaData = funnelChartItemMetaData;
}
createViewerItem(model, $element, content) {
return new FunnelChartItemViewer(model, $element, content);
}
}
return FunnelChartItem;
// #endregion
})();
Razor<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Dashboard Web Application</title>
<link href="css/site.min.css" rel="stylesheet" />
<script type="text/javascript">
function onBeforeRender(dashboardControl) {
dashboardControl.registerExtension(new DevExpress.Dashboard.DashboardPanelExtension(dashboardControl));
dashboardControl.registerExtension(new HelloWorldCustomItem(dashboardControl));
dashboardControl.registerExtension(new DataAwareCustomItem(dashboardControl));
dashboardControl.registerExtension(new FunnelChartCustomItem(dashboardControl));
}
</script>
</head>
<body>
@RenderBody()
<script src="js/site.min.js"></script>
<script src="js/HelloWorldItem.js"></script>
<script src="js/DataAwareItem.js"></script>
<script src="js/FunnelChartItem.js"></script>
</body>
</html>