I'm working with an ArcGIS Dashboard containing a layer with approximately 12,000 points, and I'm facing significant performance issues with the Category Selector widget.
The Problem: The Category Selector widget needs to display a list of unique property owners. Since there are around 5,000 unique owners in the dataset, I increased the "Maximum categories" setting accordingly. However, with this setting, the dashboard freezes for several minutes upon loading and often becomes unresponsive. My understanding is that the widget performs very intensive attribute queries against the feature service to build this complete list of 5,000 unique values during initialization, which is causing the performance bottleneck.
I know that ArcGIS Experience Builder's Search Widget handles large datasets more efficiently because it uses targeted, on-demand server-side queries instead of pre-loading the entire list of unique values.
Proposed Solution & Question: My plan is to embed my existing ArcGIS Dashboard into a new Experience Builder application. I can’t recreate the dashboard directly in Experience Builder since it’s still missing some of the features that Dashboards provide. I will remove the slow Category Selector from the dashboard itself and use Experience Builder's Search Widget to control filtering through URL parameters.
I need to configure the Experience Builder Search Widget and the Embed Widget so that when a user searches for an owner's name:
The search input gets passed to the embedded dashboard via URL parameters through the Embed Widget's dynamic URL configuration.
The embedded dashboard reads this URL parameter and filters the map and all other dashboard elements (charts, tables, etc.) to show only the data for that specific owner.
For example, searching for "Sam Walton" should filter the dashboard to display all multiple sites he owns, while searching for "Joe Dirt" would show his single site.
Could someone that knows how to do this be willing to help me out with instructions, screenshots, sometype of youtube video or willing to point me towards one of these or a tutorial demonstrating how to set up this interaction between the Search Widget and an embedded Dashboard using URL parameters?
Any help showing the proper configuration would be greatly appreciated! Also I am using ArcGIS Enterprise 11.4.
PS, sorry if this ends up sounding a bit stiff. I had AI help me clean up the grammar, and now it reads a little too much like it was written by AI. That said, it does capture my problem perfectly 🙂
Of course! Here is the revised update with that new call-to-action included.
UPDATE:
First off, thanks to everyone who took a look at this, and at the time of this post update I only had one response from " JeffreyThompson2 " and I think him for the advice and I wanted to share my journey and the final outcome for anyone who might run into a similar issue in the future.
I went ahead with the plan to embed my Dashboard in Experience Builder and use the Search widget to pass a URL parameter. After a lot of configuration, I got it partially working, but I ultimately ran into two major roadblocks that made the solution unworkable:
The Blank Dashboard Problem: The embedded dashboard was completely blank on the initial load. It would only appear after I performed a search and selected a result. This happened because the Embed widget was configured to use the "Selected features" data view to build its URL. With no initial selection, the URL parameter was empty, resulting in a broken link (...#current_controller_name=).
Un-grouped Search Results: My Search widget was correctly searching the owner name field. However, when I searched for a company like "Rogers Group Inc" which owns 50+ sites, the search results would list every single one of those sites individually. I then had to click one of the sites from that long list to trigger the filter. While the dashboard did correctly filter to show all 50 Rogers Group sites after that second click, the user experience of a two-step selection was clunky and not what I was aiming for.
I tried several different workarounds, including various dynamic URL expressions and switching to the "Embed by Code" <iframe> method, but I couldn't get it to a state that felt polished and reliable.
My Conclusion & Final Solution:
While the embedding method is technically possible, I've concluded that it's ultimately a fragile and clunky workaround for my needs. The best path forward is to abandon the embedding idea and rebuild the dashboard's functionality natively within Experience Builder.
Experience Builder has its own powerful Table and Chart widgets that can be filtered directly by the Search widget and the map extent using built-in Actions. This native approach will be more stable, perform much better, and completely solves my original problem with the slow Category Selector. I'll lose a few minor perks from the Dashboards environment, but the trade-off for a fast and seamlessly integrated application is well worth it.
P.S. If anyone in the future figures out a reliable way to defeat both of my stumbling blocks (The Blank Dashboard Problem and Un-grouped Search Results), please chime in on this thread! A link to a tutorial, video, or a detailed write-up would be amazing. I'm sure it would make life a lot easier for others who stumble across this and would prefer not to rebuild their entire dashboard.
For anyone curious, here's a sanitized and trimmed version of my Experience Builder app's .json configuration from when I was trying to make the embedding work. It shows how the Search widget (widget_2) was set up to send a DATA_RECORDS_SELECTION_CHANGE message, and how the Embed widget (widget_3) was configured to listen for that selection to build its URL.
{
"widgets": {
"widget_2": {
"uri": "widgets/common/search/",
"label": "Search",
"config": {
"datasourceConfig": [{
"label": "controller name",
"useDataSource": {
"dataSourceId": "dataSource_2-0",
"mainDataSourceId": "dataSource_2-0",
"rootDataSourceId": "dataSource_2"
},
"displayFields": [{
"jimuName": "current_controller_name",
"name": "current_controller_name"
}],
"searchFields": [{
"jimuName": "current_controller_name",
"name": "current_controller_name"
}]
}]
},
"id": "widget_2"
},
"widget_3": {
"uri": "widgets/common/embed/",
"label": "Embed",
"config": {
"embedType": "url",
"expression": "<p>https://gis.my-company.com/portal/apps/dashboards/7f16ee769a9e4048809bd458e078d5d7#current_controller_name=<exp data-uniqueid=\"d47e...\" data-dsid=\"dataSource_2-0-selection\" data-expression=\"{CURRENT_CONTROLLER_NAME}\"><span contenteditable=\"false\">{CURRENT_CONTROLLER_NAME}</span></exp></p>"
},
"id": "widget_3",
"useDataSources": [{
"dataSourceId": "dataSource_2-0-selection",
"mainDataSourceId": "dataSource_2-0",
"rootDataSourceId": "dataSource_2",
"fields": [
"current_controller_name"
],
"dataViewId": "selection"
}],
"useDataSourcesEnabled": true
}
},
"dataSources": {
"dataSource_2": {
"id": "dataSource_2",
"type": "FEATURE_SERVICE",
"itemId": "d864c7e03df3489591dcfc3c47e66c74",
"portalUrl": "https://gis.my-company.com/portal",
"url": "https://gis.my-company.com/server/rest/services/MASTER_DATA_SOURCE/FeatureServer"
}
},
"messageConfigs": {
"messageConfig_1": {
"id": "messageConfig_1",
"widgetId": "widget_2",
"messageType": "DATA_RECORDS_SELECTION_CHANGE",
"actions": [{
"actionName": "select data record action",
"config": {
"actionUseDataSource": {
"dataSourceId": "dataSource_2-0",
"rootDataSourceId": "dataSource_2"
},
"messageUseDataSource": {
"dataSourceId": "dataSource_2-0",
"rootDataSourceId": "dataSource_2"
}
}
}]
}
}
}