▾
For an introduction to tracing in utility networks, start with Trace a utility network.
The Utility Network Trace Analysis component provides an interactive workflow for choosing a named trace configuration, placing trace locations, executing a trace, and exploring its results.
This guide first demonstrates how to use the Utility Network Trace Analysis component, then shows how to customize inputs, execution, and result presentation for custom trace workflows.
Run a trace with Utility Network Trace Analysis
The Utility Network Trace Analysis component provides controls for selecting a utility network and named trace configuration, adding starting points and barriers, running the trace, and viewing trace results. It also displays any errors that occur during the trace.
Add the Utility Network Trace Analysis component to a Map component that displays a web map. The web map must contain a utility network and shared named trace configurations.
Configure authentication for secured services before loading the map. See Introduction to utility networks for details on loading a utility network in the ArcGIS Maps SDK for JavaScript.
Slotted into the Map component:
<arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310"> <arcgis-utility-network-trace-analysis slot="bottom-left" ></arcgis-utility-network-trace-analysis></arcgis-map>To render the component outside of the Map component, use reference-element:
<arcgis-map id="my-map" item-id="471eb0bf37074b1fbb972b1da70fb310"></arcgis-map><arcgis-utility-network-trace-analysis reference-element="my-map"></arcgis-utility-network-trace-analysis>For more details, see Associate components with a Map or Scene component.
Once the map and component have loaded, users can run a trace through the Utility Network Trace Analysis component’s interface:
-
Choose a network and trace configuration. On the Inputs tab, select a utility network if the map contains more than one, then select a named trace configuration. For subnetwork-based traces, the component displays the configured domain network, tier, and target tier. Changing the utility network clears previously added trace locations.
-
Set trace locations. Use the starting-point or barrier controls to select a feature on the map, inspect the candidate features, and add a feature as a trace location. Starting points define where the trace begins; barriers limit where it can traverse. Users can select terminals for features that have them. Path traces also provide stopping-point controls. For a subnetwork trace configured with a subnetwork name, users choose a subnetwork instead of adding starting points.
Nonspatial objects can also serve as trace locations. Select an associated spatial feature, navigate its associations, and add the target object. To enable this workflow, the spatial feature’s layer must have a PopupTemplate containing UtilityNetworkAssociationsContent.
-
Run the trace. Select Get trace results. The component warns about missing starting points or terminal selections before executing the trace. It switches to the Results tab and displays a progress indicator while the trace runs. If any errors occur during the trace, the error(s) display in the results tab.
-
Inspect the results. Depending on the result types requested by the configuration, the component displays returned elements as features, aggregated geometries, and function results. Users can browse feature results and inspect their attributes, while returned features are highlighted on the map by default.
Select Clear results to remove the current results and return to the Inputs tab. Users can adjust the inputs and run another trace; each run replaces the previous result. To retain multiple results for comparison, use the separate result components described below.
Trace subcomponents
Trace subcomponents, added at version 5.2, are reusable components for individual parts of a utility network trace workflow, from selecting inputs to presenting results. Use them to customize result presentation within the Utility Network Trace Analysis component or combine them in a custom workflow. For example, you can use these subcomponents independently of the Utility Network Trace Analysis component to place input controls in a sidebar, run traces from an application button, and display multiple trace results in a pane.
The subcomponents do not execute traces themselves. Utility Network Trace Analysis runs the trace and supplies necessary context like the view, utility network, and trace result to its result components. When using subcomponents without Utility Network Trace Analysis, your application handles trace execution and supplies that context.
- Utility Network Trace Inputs collects trace inputs through combined network selection, named trace configuration selection, and trace location/subnetwork name controls.
- Utility Network Picker selects a utility network from the web map.
- Utility Network Trace Configuration Picker selects a named trace configuration and, when applicable, a subnetwork.
- Utility Network Trace Locations selects and manages starting points, barriers, and stopping points.
- Utility Network Trace Results Pane organizes one or more trace results, each displayed by a Utility Network Trace Results component.
- Utility Network Trace Results displays the outcome of one trace, including returned results, an empty result, or an error.
- Utility Network Trace Elements Result Item displays features corresponding to trace result elements.
- Utility Network Trace Aggregated Geometry Result Item displays trace result aggregated geometries on a map.
- Utility Network Trace Functions Result Item displays trace function results in a table.
Configure trace inputs
Use Utility Network Trace Inputs to collect trace inputs in one interface, or use Utility Network Picker, Utility Network Trace Configuration Picker, and Utility Network Trace Locations for individual controls. These components collect utility network, named trace configuration, and trace location information; they do not run traces.
Utility Network Trace Inputs
Utility Network Trace Inputs combines utility network selection, named trace configuration selection, and trace location selection. Use this component when you want those controls together but need the application to decide when and how to execute the trace.
Supply a ready MapView through view. Its web map must contain a utility network, the network’s layers, and shared named trace configurations. Configure authentication before loading the map if required.
The following example displays the input controls alongside the Map component:
<calcite-shell> <calcite-shell-panel slot="panel-start"> <arcgis-utility-network-trace-inputs></arcgis-utility-network-trace-inputs> </calcite-shell-panel> <arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310"></arcgis-map></calcite-shell>import "@arcgis/map-components/components/arcgis-map";import "@arcgis/map-components/components/arcgis-utility-network-trace-inputs";
const mapElement = document.querySelector("arcgis-map");const inputs = document.querySelector("arcgis-utility-network-trace-inputs");await Promise.all([mapElement.viewOnReady(), inputs.componentOnReady()]);
inputs.view = mapElement.view;
// Optional: choose an initial network; otherwise, the component selects the first available network.inputs.selectedUtilityNetwork = mapElement.map.utilityNetworks.at(0);The component selects the first available utility network in the map and loads it if needed. Set selectedUtilityNetwork to a network from the web map to choose a different initial network. Changing the network clears existing trace locations and refreshes the available named trace configurations.
Users choose a named trace configuration and add starting points and barriers. Path traces also provide stopping-point controls. For subnetwork traces configured with a subnetwork name, users select a subnetwork instead of adding starting points.
When executing a trace, read the component’s current values:
- selectedUtilityNetwork: the selected network.
- selectedNamedTraceConfiguration: the selected named configuration, including its trace type and result types.
- traceConfiguration: a working copy of
selectedNamedTraceConfiguration.traceConfigurationthat reflects current input settings without modifying the original named configuration. - traceLocations: trace locations usable as inputs to
UtilityNetwork.trace(), assembled from starting points, barriers, and stopping points as needed by the selected named trace configuration.
Depending on user input to the Utility Network Trace Inputs component, the returned trace locations may be empty or lack required terminal selections. See the traceLocations property documentation for details. Your application must validate the trace configuration and locations before executing the trace. See Execute traces without Utility Network Trace Analysis to connect the controls to an application-provided run button and result display.
Utility Network Picker
Utility Network Picker lets users select a utility network from a web map. Use it when building a trace input interface with individual controls rather than the combined Utility Network Trace Inputs component. It does not select a named trace configuration or execute traces.
Set view to a ready MapView whose map is a web map containing utility networks. Configure authentication before loading the map if required.
The following example displays the picker alongside the Map component and reads the selected network’s named trace configurations:
<calcite-shell> <calcite-shell-panel slot="panel-start" width-scale="l"> <arcgis-utility-network-picker></arcgis-utility-network-picker> </calcite-shell-panel> <arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310" popup-disabled></arcgis-map></calcite-shell>import "@arcgis/map-components/components/arcgis-map";import "@arcgis/map-components/components/arcgis-utility-network-picker";
const mapElement = document.querySelector("arcgis-map");const networkPicker = document.querySelector("arcgis-utility-network-picker");await Promise.all([mapElement.viewOnReady(), networkPicker.componentOnReady()]);
networkPicker.addEventListener("arcgisError", () => { console.error("Utility network picker:", networkPicker.error);});
networkPicker.addEventListener("arcgisPropertyChange", async (event) => { if (event.detail.name !== "selectedUtilityNetwork") { return; }
const network = networkPicker.selectedUtilityNetwork; if (!network) { console.error("No utility network is selected."); return; }
try { await network.load(); if (networkPicker.selectedUtilityNetwork !== network) { return; }
console.log("Selected network:", network.title); console.log("Named trace configurations:", network.sharedNamedTraceConfigurations); } catch (error) { console.error("Unable to load the selected utility network:", error); }});
networkPicker.view = mapElement.view;
// Optional: override the default heading.networkPicker.heading = "Choose a network";
// Optional: choose an initial network; otherwise, the picker selects the first available network.networkPicker.selectedUtilityNetwork = mapElement.map.utilityNetworks.at(0);The picker reads the web map’s utilityNetworks collection. With one network, it displays the network’s title; with multiple networks, it displays a combobox. It selects the first available network unless a valid selection is supplied through selectedUtilityNetwork.
The picker loads the selected network if needed, but a selection change does not mean loading has finished. Await utilityNetwork.load() before using its data, as shown above. componentOnReady() waits for component initialization, not for the selected network to load.
Utility Network Trace Configuration Picker
Utility Network Trace Configuration Picker presents named trace configurations for a utility network. Use it instead of the combined Utility Network Trace Inputs component when an application already manages network selection and trace locations.
Set utilityNetwork to a loaded utility network and supply its named configurations through traceConfigurations. Setting the network alone does not populate the configuration list. This component does not require a view and does not execute traces.
In this example, utilityNetwork is already loaded and has shared named trace configurations:
<arcgis-utility-network-trace-configuration-picker></arcgis-utility-network-trace-configuration-picker>import "@arcgis/map-components/components/arcgis-utility-network-trace-configuration-picker";
const picker = document.querySelector("arcgis-utility-network-trace-configuration-picker");await picker.componentOnReady();
picker.addEventListener("arcgisPropertyChange", (event) => { if (event.target === picker && event.detail.name === "selectedNamedTraceConfiguration") { console.log("Selected named trace configuration:", picker.selectedNamedTraceConfiguration); console.log("Trace configuration:", picker.traceConfiguration); }});
picker.utilityNetwork = utilityNetwork;picker.traceConfigurations = utilityNetwork.sharedNamedTraceConfigurations;The component displays a title for a single configuration or a combobox for multiple configurations. Replacing traceConfigurations selects the first entry containing a valid UNTraceConfiguration. For subnetwork traces configured with a subnetwork name, users can also select a compatible subnetwork.
Read these properties when executing a trace:
- selectedNamedTraceConfiguration: the selected named configuration, including its trace type and result types.
- traceConfiguration: an editable clone of the selected configuration that reflects current settings without modifying the original.
The arcgisPropertyChange event reports selection changes and replacement of the working configuration. Changes to fields within that configuration, including the subnetwork name, do not emit this event. The configuration logged in the example can therefore change afterward; read the current traceConfiguration when running the trace rather than relying on the listener to capture every edit.
Utility Network Trace Locations
Utility Network Trace Locations provides controls for selecting trace locations of a particular type from features on a map. Users can add locations from the map, remove locations, and select terminals where applicable. Use multiple instances of this component to collect trace locations of different types, e.g., starting points and barriers.
Set these properties before users select locations:
- view: a ready MapView.
- utilityNetwork: a loaded utility network. The component does not automatically load the provided utility network.
- filterLayers: the network’s feature or subtype group layers available for selection and snapping. This collection is empty by default, so users cannot select locations until this collection is set.
- traceLocationType: the location type to create, e.g.,
"starting-point"or"barrier". Defaults to"starting-point".
The following example displays separate starting-point and barrier controls alongside the Map component. The web map must contain a utility network and its layers. Configure authentication before loading the map if required.
<calcite-shell> <calcite-shell-panel slot="panel-start" width-scale="l"> <arcgis-utility-network-trace-locations id="starting-points" trace-location-type="starting-point" ></arcgis-utility-network-trace-locations> <arcgis-utility-network-trace-locations id="barriers" trace-location-type="barrier" ></arcgis-utility-network-trace-locations> </calcite-shell-panel> <arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310" popup-disabled></arcgis-map></calcite-shell>import "@arcgis/map-components/components/arcgis-map";import "@arcgis/map-components/components/arcgis-utility-network-trace-locations";
const mapElement = document.querySelector("arcgis-map");const startingPoints = document.getElementById("starting-points");const barriers = document.getElementById("barriers");const locationControls = [startingPoints, barriers];
await Promise.all([ mapElement.viewOnReady(), ...locationControls.map((control) => control.componentOnReady()),]);
const utilityNetwork = mapElement.map.utilityNetworks.at(0);await utilityNetwork.load();
const filterLayers = mapElement.map.allLayers.filter( (layer) => utilityNetwork.isUtilityLayer(layer) && (layer.type === "feature" || layer.type === "subtype-group"),);
for (const control of locationControls) { control.view = mapElement.view; control.utilityNetwork = utilityNetwork; control.filterLayers = filterLayers;
control.addEventListener("arcgisTraceLocationSelectStart", () => { console.log("Trace location selection started:", control.traceLocationType); });
control.addEventListener("arcgisTraceLocationSelectEnd", () => { console.log(control.traceLocationType, control.traceLocations.toArray()); });
control.addEventListener("arcgisError", () => { console.error("Trace location selection failed:", control.error); });}Each trace locations component instance maintains its own traceLocations collection. The arcgisTraceLocationSelectEnd handler logs the current collection, not necessarily a newly added location: the event also fires when selection is canceled or ends without adding a usable feature.
To prevent selection from starting when another application interaction must take precedence, call preventDefault() on arcgisTraceLocationSelectStart. For example, temporarily block starting point selection while another tool is active:
function preventStartingPointSelection(event) { event.preventDefault();}
startingPoints.addEventListener("arcgisTraceLocationSelectStart", preventStartingPointSelection);When that tool is deactivated, remove the listener to allow starting-point selection again:
startingPoints.removeEventListener("arcgisTraceLocationSelectStart", preventStartingPointSelection);Handle arcgisError to report selection errors and warnings. The component does not display its error message itself; replace the example’s console logging with user-visible feedback in your application.
This example collects trace location details; it does not execute a trace. Unlike Utility Network Trace Inputs, this component returns a collection of TraceLocationDetails objects rather than an array of TraceLocation objects. Your application must translate these TraceLocationDetails objects into trace locations and account for terminal selections, edge positions, and the selected trace type. Terminal choices are stored in each entry’s flagProperties.selectedTerminals; using only its traceLocation.terminalId does not account for those choices. Prefer Utility Network Trace Inputs when you want the combined component to perform the conversion for you.
Customize result presentation with trace result items
A trace result is the data returned by one trace operation. Utility Network Trace Results presents one trace result using trace result item components, each responsible for a particular trace result type: elements, aggregated geometry, or functions. A result item represents a presentation of one result type for a trace result.
By default, Utility Network Trace Analysis displays these result items for the supported result types returned by the trace; no custom result markup is needed. Customize the result items when you want to choose which result types appear, or configure the presentation of individual result items.
To customize result presentation inside Utility Network Trace Analysis:
- Add a Utility Network Trace Results component as a direct child with
slot="results". Utility Network Trace Analysis supplies its traceResult, traceError, utilityNetwork, and view. - Add result item components as direct children in the default slot of Utility Network Trace Results, without a
slotattribute. This replaces its entire default set of result items. The Utility Network Trace Results component supplies each item with the trace result and any utility network or view context it needs.
<arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310"> <arcgis-utility-network-trace-analysis slot="bottom-left"> <arcgis-utility-network-trace-results slot="results"> <arcgis-utility-network-trace-elements-result-item heading="Network features" ></arcgis-utility-network-trace-elements-result-item> <arcgis-utility-network-trace-aggregated-geometry-result-item heading="Trace geometry" ></arcgis-utility-network-trace-aggregated-geometry-result-item> <arcgis-utility-network-trace-functions-result-item heading="Function results" ></arcgis-utility-network-trace-functions-result-item> </arcgis-utility-network-trace-results> </arcgis-utility-network-trace-analysis></arcgis-map>This example customizes the headings for all three result items while retaining presentation of trace result elements, aggregated geometry, and functions when those result types are returned by the trace. Adding a result item component does not request that result type from the service; the trace configuration must specify the result type.
Utility Network Trace Elements Result Item
Utility Network Trace Elements Result Item queries and displays features associated with the network elements returned by a trace. Use it for inspecting result features and interacting with them on the map. Its Utility Network Trace Results parent supplies the trace result, utility network, and view.
The component highlights trace elements on the map by default and displays queried features in a list. For a trace containing only element results, the list opens automatically. With multiple result types, users open the list by selecting the elements result item.
The following example displays only element results and disables highlighting the corresponding features on the map:
<arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310"> <arcgis-utility-network-trace-analysis slot="bottom-left"> <arcgis-utility-network-trace-results slot="results"> <arcgis-utility-network-trace-elements-result-item heading="Network features" disable-highlight ></arcgis-utility-network-trace-elements-result-item> </arcgis-utility-network-trace-results> </arcgis-utility-network-trace-analysis></arcgis-map>To limit the queried and displayed features to particular utility network layers or tables, set layers directly on the Utility Network Trace Elements Result Item component before running a trace. In this example, queryLayers is an application-provided array of layers or tables belonging to the utility network used by the trace. Layers from another utility network, or layers not belonging to any utility network, are ignored.
import "@arcgis/map-components/components/arcgis-map";import "@arcgis/map-components/components/arcgis-utility-network-trace-analysis";import "@arcgis/map-components/components/arcgis-utility-network-trace-results";import "@arcgis/map-components/components/arcgis-utility-network-trace-elements-result-item";
const elementsResultItem = document.querySelector("arcgis-utility-network-trace-elements-result-item");await elementsResultItem.componentOnReady();elementsResultItem.layers = queryLayers;
elementsResultItem.addEventListener("arcgisPropertyChange", (event) => { if (event.target === elementsResultItem && event.detail.name === "state") { console.log("Feature query state:", elementsResultItem.state); }});
elementsResultItem.addEventListener("arcgisResultReady", () => { console.log("Queried element features:", elementsResultItem.features);});An empty layers array uses the map’s layers and tables that belong to the utility network. Restricting this array limits feature queries, not highlighting. Set it before the trace result is processed; changing it does not requery the current result. When using the default result items instead of supplying your own, configure the layers property on the Utility Network Trace Results component, which does not affect slotted result items.
The disableHighlight property disables map highlighting independently of feature browsing. Conversely, hideFeatureResults hides feature browsing but still queries features and does not disable highlighting.
Utility Network Trace Elements Result Item asynchronously queries utility network features corresponding to the trace result elements. Its state is "loading" while processing the result and "ready" when no processing is in progress. Observe state changes through arcgisPropertyChange, or listen for arcgisResultReady before reading features, as shown above. Completion does not guarantee every query succeeded; features contains successfully queried features and excludes elements without a matching query layer.
Utility Network Trace Functions Result Item
Utility Network Trace Functions Result Item displays calculated values returned by a trace in a table of function names and values. Its Utility Network Trace Results parent supplies the trace result. The component displays the trace result’s globalFunctionResults; it does not execute calculations or query features.
Each row uses the function name when available, or the network attribute name and function type otherwise. Results missing a network attribute name, function type, or result value are omitted. When the trace returns no function results, the component displays no content.
The following example displays only function results and customizes the table heading:
<arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310"> <arcgis-utility-network-trace-analysis slot="bottom-left"> <arcgis-utility-network-trace-results slot="results"> <arcgis-utility-network-trace-functions-result-item heading="Function results" ></arcgis-utility-network-trace-functions-result-item> </arcgis-utility-network-trace-results> </arcgis-utility-network-trace-analysis></arcgis-map>Providing this result item replaces the default result items. Function results appear only when returned by the trace; adding Utility Network Trace Functions Result Item does not request calculations from the service. The trace configuration must request the function results to display.
Unlike Utility Network Trace Elements Result Item, this component requires no asynchronous feature queries, so its state is always "ready". To be notified when it processes a new trace result, listen for arcgisResultReady, which also fires when the result contains no function results.
Utility Network Trace Aggregated Geometry Result Item
Utility Network Trace Aggregated Geometry Result Item creates map graphics from the line, multipoint, and polygon geometries in the trace result’s aggregatedGeometry. It does not query features or calculate the geometry itself. Its Utility Network Trace Results parent supplies the traceResult and view properties.
Utility Network Trace Aggregated Geometry Result Item provides controls within the Utility Network Trace Results interface for users to toggle the graphics on and off and change their color. Programmatically, configure graphicsColor to change the graphics’ color and selectionSize to set marker size and line or polygon-outline width in points.
The following example customizes the heading, color, and size while displaying only aggregated geometry results:
<arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310"> <arcgis-utility-network-trace-analysis slot="bottom-left"> <arcgis-utility-network-trace-results slot="results"> <arcgis-utility-network-trace-aggregated-geometry-result-item heading="Trace geometry" graphics-color="rgba(0, 122, 194, 0.6)" selection-size="8" ></arcgis-utility-network-trace-aggregated-geometry-result-item> </arcgis-utility-network-trace-results> </arcgis-utility-network-trace-analysis></arcgis-map>Providing this result item replaces the default result items. Aggregated geometry appears only when returned by the trace; adding Utility Network Trace Aggregated Geometry Result Item does not request that result type from the service.
Observe state through arcgisPropertyChange to track result processing: "loading" means the result item component is adding graphics to the map, and "ready" means no processing is in progress. Read geometryGraphics after arcgisResultReady fires:
import "@arcgis/map-components/components/arcgis-map";import "@arcgis/map-components/components/arcgis-utility-network-trace-analysis";import "@arcgis/map-components/components/arcgis-utility-network-trace-results";import "@arcgis/map-components/components/arcgis-utility-network-trace-aggregated-geometry-result-item";
const geometryResultItem = document.querySelector("arcgis-utility-network-trace-aggregated-geometry-result-item");await geometryResultItem.componentOnReady();
geometryResultItem.addEventListener("arcgisPropertyChange", (event) => { if (event.target === geometryResultItem && event.detail.name === "state") { console.log("Geometry processing state:", geometryResultItem.state); }});
geometryResultItem.addEventListener("arcgisResultReady", () => { console.log("Aggregated geometry graphics:", geometryResultItem.geometryGraphics);});The arcgisResultReady event can also fire without graphics, for example when aggregated geometry or the view is unavailable. It does not guarantee that graphics were displayed.
Set hideGraphics to hide the graphics from the map while keeping them available through geometryGraphics. Set graphicsLayer to use an application-provided layer; otherwise, the component creates and manages its own layer.
When the result is cleared or the component is destroyed, it removes its aggregated geometry graphics. Unrelated graphics on an application-provided layer remain unchanged. If the component created the layer, it also removes that layer from the map.
Implement custom result items
Create a custom result item to render in the Utility Network Trace Results component when your application needs a behavior or result type presentation beyond the default result items. Any element added to the trace results component’s default slot will render, including ordinary HTML elements, Calcite components, or custom elements, alongside any built-in result items you explicitly include. An element is not strictly required to implement UtilityNetworkTraceResultItem to render; rather, use that interface as a reference for any context, readiness, or cleanup behavior your item may need.
Custom result items can be used anywhere Utility Network Trace Results is used: as a child of Utility Network Trace Analysis or independently in a custom trace workflow. In either case, add your custom element as a child in the Utility Network Trace Results component’s default slot. Any slotted content replaces the entire default set of result items, so include each default or custom item you want to display.
For a minimal example, slot a Calcite Button beside the built-in elements result item to download TraceResult.sourceJSON, the full trace response as a JSON object. The downloadBlobAsFile() function handles the browser download and releases its download URL, so no download resources need to be retained or cleared between trace results.
<arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310"> <arcgis-utility-network-trace-analysis slot="bottom-left"> <arcgis-utility-network-trace-results slot="results" expanded> <arcgis-utility-network-trace-elements-result-item></arcgis-utility-network-trace-elements-result-item> <calcite-button id="download-trace">Download trace JSON</calcite-button> </arcgis-utility-network-trace-results> </arcgis-utility-network-trace-analysis></arcgis-map>import "@arcgis/map-components/components/arcgis-map";import "@arcgis/map-components/components/arcgis-utility-network-trace-analysis";import "@arcgis/map-components/components/arcgis-utility-network-trace-results";import "@arcgis/map-components/components/arcgis-utility-network-trace-elements-result-item";import "@esri/calcite-components/components/calcite-button";
import { downloadBlobAsFile } from "@arcgis/core/core/urlUtils.js";
const results = document.querySelector("arcgis-utility-network-trace-results");const downloadButton = document.getElementById("download-trace");await results.componentOnReady();
downloadButton.addEventListener("click", () => { const blob = new Blob([JSON.stringify(results.traceResult.sourceJSON, null, 2)], { type: "application/json", }); downloadBlobAsFile(blob, "trace-result.json");});Read context from the parent
Unlike built-in result items, custom items do not automatically receive traceResult, utilityNetwork, or view. Read the properties your item needs from its Utility Network Trace Results parent. Listen for the parent’s arcgisPropertyChange event to process subsequent changes, ignoring events whose target is not the parent. Handle an undefined traceResult when no result is available, and replace previous output when a new result arrives. Remove your listeners when the custom item disconnects.
Configure item-specific settings, such as a heading or layers to query, directly on your custom item. The parent’s heading labels the whole trace, and its layers configuration is forwarded only to its internally created elements result item.
For data not exposed directly by the TraceResult class, use TraceResult.sourceJSON, which represents the entire trace result REST response as a JSON object.
Participate in result readiness
Set emitsArcgisResultReady to true on your custom result item before adding the item to Utility Network Trace Results if the parent should wait for the custom result item’s processing to finish before displaying results. Dispatch arcgisResultReady from the custom item when processing finishes; no event detail is required. The parent stays in its "loading" state until all participating items finish, then emits arcgisResultsReady.
Readiness means processing has finished, not necessarily that it succeeded. If the custom result item sets emitsArcgisResultReady to true, it must emit the event even when the current trace result has no applicable results or processing fails. Otherwise, the parent keeps waiting. If processing fails, display an error message before signaling completion. Do not signal completion for work canceled because the result was cleared or replaced.
Set emitsArcgisResultReady to false for content that does not need to delay readiness (e.g., see the example above to download trace results).
Clear output and cancel pending work
Implement a synchronous clearResult() method to clear any stored trace result and rendered output, cancel pending work, and undo side effects such as graphics or highlights owned by your custom result item. Utility Network Trace Results calls this method on child result items that implement it when its trace result changes or its clearResults() method is called.
Cleanup must be safe to repeat. Ensure canceled work cannot restore stale output or emit arcgisResultReady. Cleanup must not destroy the item, remove its context listeners, or emit a readiness event itself: the custom result item should remain available for the next trace result.
Cleanup is independent of readiness, so an item that opts out of emitsArcgisResultReady can still implement clearResult().
Example: query facilities intersecting trace geometry
For an item that needs both readiness participation and cleanup, query an application-provided FeatureLayer for the number of facilities intersecting the trace’s aggregated line geometry. The trace must specify aggregated geometry as a result type and return line geometry.
Replace the download button in the preceding markup with this custom element, keeping it beside the built-in elements result item:
<my-trace-facility-count></my-trace-facility-count>Keep the ArcGIS component imports from the first example, but replace its download-button code with the following. Here, facilitiesLayer is a loaded, application-provided FeatureLayer that supports spatial queries. Make it available before registering the custom element.
class TraceFacilityCount extends HTMLElement { emitsArcgisResultReady = true; #parent; #controller;
connectedCallback() { this.#parent = this.closest("arcgis-utility-network-trace-results"); this.#parent.addEventListener("arcgisPropertyChange", this.#handleParentChange); this.#processResult(); }
disconnectedCallback() { this.#parent.removeEventListener("arcgisPropertyChange", this.#handleParentChange); this.clearResult(); this.#parent = undefined; }
#handleParentChange = (event) => { if (event.target === this.#parent && event.detail.name === "traceResult") { this.#processResult(); } };
async #processResult() { this.clearResult(); const traceResult = this.#parent.traceResult; if (!traceResult) { this.textContent = "Run a trace to see intersecting facilities."; return; }
const controller = new AbortController(); this.#controller = controller;
try { const queryGeometry = traceResult.aggregatedGeometry?.line; if (!queryGeometry) { this.textContent = "No aggregated line geometry was returned."; return; }
const query = facilitiesLayer.createQuery(); query.geometry = queryGeometry; query.spatialRelationship = "intersects"; const count = await facilitiesLayer.queryFeatureCount(query, { signal: controller.signal, });
if (!controller.signal.aborted) { this.textContent = !count ? "No facilities intersect this trace's line geometry." : `Facilities intersecting trace geometry: ${count}`; } } catch (error) { if (!controller.signal.aborted) { console.error("Could not query facilities:", error); this.textContent = "Could not query facilities for this trace."; } } finally { if (this.#controller === controller) { this.#controller = undefined; this.dispatchEvent(new CustomEvent("arcgisResultReady")); } } }
clearResult() { this.#controller?.abort(); this.#controller = undefined; this.replaceChildren(); }}
customElements.define("my-trace-facility-count", TraceFacilityCount);The item emits arcgisResultReady after a successful query, an empty-geometry result, or a displayed query error. Its clearResult() method aborts an in-flight query, invalidates the controller, and clears the displayed count or error. Disconnecting also removes the parent listener, while ordinary cleanup leaves it in place.
Execute traces without Utility Network Trace Analysis
Run traces in your application code when you need to control when a trace runs or display results separately from the input controls. Your application must track trace execution, handle errors, and supply the results to the result components.
The following example uses Utility Network Trace Inputs to gather inputs, calls UtilityNetwork.trace() from an application-rendered button, and displays one result with Utility Network Trace Results. It uses Calcite Components to organize the input and result components into separate tabs in a panel beside the map and provide a run button with a loading indicator. Each run replaces the previous result.
The web map must contain a utility network, its layers, and shared named trace configurations. Configure authentication before loading the map if required.
<calcite-shell> <calcite-shell-panel slot="panel-start" width-scale="l"> <calcite-panel heading="Utility network trace"> <calcite-tabs layout="center"> <calcite-tab-nav slot="title-group"> <calcite-tab-title selected>Inputs</calcite-tab-title> <calcite-tab-title id="results-tab">Results</calcite-tab-title> </calcite-tab-nav> <calcite-tab selected> <arcgis-utility-network-trace-inputs></arcgis-utility-network-trace-inputs> </calcite-tab> <calcite-tab> <arcgis-utility-network-trace-results heading="Trace result" expanded></arcgis-utility-network-trace-results> </calcite-tab> </calcite-tabs> <p id="trace-message" role="status"></p> <calcite-button slot="footer" width="full" disabled>Run trace</calcite-button> </calcite-panel> </calcite-shell-panel> <arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310" popup-disabled></arcgis-map></calcite-shell>Register these components before initializing them:
import "@arcgis/map-components/components/arcgis-map";import "@arcgis/map-components/components/arcgis-utility-network-trace-inputs";import "@arcgis/map-components/components/arcgis-utility-network-trace-results";Initialize the input and result components with the Map component’s view, as in the earlier subcomponent examples. Utility Network Trace Inputs selects and loads the first available network by default. Users choose a named trace configuration and add the locations it requires. When the run button is clicked, read property values from the Utility Network Trace Inputs component and pass them to UtilityNetwork.trace().
Unlike the earlier result item examples nested inside Utility Network Trace Analysis, this standalone Utility Network Trace Results component receives its context from the developer’s application code. Set its view and utilityNetwork before assigning traceResult. This example uses the default result items and assigns trace errors to traceError for display. No slot="results" attribute is needed outside Utility Network Trace Analysis.
Before running a new trace, the example calls clearResults() to clear side effects from the previous trace result, like aggregated geometries on the map or feature highlights.
The run button’s loading indicator tracks the trace request and stops when the request finishes. The panel remains in its loading state while the result items process the response, e.g., asynchronous feature queries. When Utility Network Trace Results emits arcgisResultsReady, the example clears the panel’s loading state and switches to the Results tab before reading traceResultFeatures. If the trace request fails, it also clears the panel’s loading state and switches to that tab so users can see the error.
This example uses a web map with a single utility network, loaded and assigned during setup. It checks that a trace configuration is selected, but does not validate required starting points, subnetwork names, or terminal selections. Add validation for the selected trace type before executing a trace in a production application.
const mapElement = document.querySelector("arcgis-map");const inputs = document.querySelector("arcgis-utility-network-trace-inputs");const results = document.querySelector("arcgis-utility-network-trace-results");const runButton = document.querySelector("calcite-button");const panel = document.querySelector("calcite-panel");const resultsTabTitle = document.getElementById("results-tab");const message = document.getElementById("trace-message");
await Promise.all([ mapElement.viewOnReady(), inputs.componentOnReady(), results.componentOnReady(), runButton.componentOnReady(), panel.componentOnReady(), resultsTabTitle.componentOnReady(),]);
inputs.view = mapElement.view;results.view = mapElement.view;
const network = mapElement.map.utilityNetworks.at(0);if (!network) { throw new Error("The web map must contain a utility network.");}
await network.load();
inputs.selectedUtilityNetwork = network;results.utilityNetwork = network;runButton.disabled = false;
runButton.addEventListener("click", async () => { const namedConfiguration = inputs.selectedNamedTraceConfiguration; const configuration = inputs.traceConfiguration;
if (!namedConfiguration?.traceType || !configuration) { message.textContent = "Select a named trace configuration first."; return; }
runButton.disabled = true; runButton.loading = true; message.textContent = ""; results.clearResults(); panel.loading = true;
try { results.traceResult = await network.trace({ traceType: namedConfiguration.traceType, traceConfiguration: configuration, traceLocations: inputs.traceLocations, resultTypes: namedConfiguration.resultTypes, outSpatialReference: mapElement.view.spatialReference, }); } catch (error) { results.traceError = error; panel.loading = false; resultsTabTitle.selected = true; } finally { runButton.disabled = false; runButton.loading = false; }});
results.addEventListener("arcgisResultsReady", () => { panel.loading = false; resultsTabTitle.selected = true; console.log("Queried result features:", results.traceResultFeatures);});Compare multiple trace results
Utility Network Trace Results Pane groups one or more Utility Network Trace Results components in a shared container. Use it to retain multiple results for comparison instead of replacing a single result after each trace. For example, display upstream and downstream results together, each with its own heading, display settings, and result items.
The pane does not collect inputs or execute traces. Your application must assign view, utilityNetwork, and traceResult to each Utility Network Trace Results component independently.
The following example assumes your application already has two trace results from a custom workflow, such as the one in Execute traces without Utility Network Trace Analysis. It displays them beside the map in a Calcite Shell and Panel layout. Add each Utility Network Trace Results component to the pane’s default slot. Its expandable attribute lets users expand and collapse individual results. The expanded property defaults to false, so set the expanded attribute on each Utility Network Trace Results component to make its result content initially visible.
import "@arcgis/map-components/components/arcgis-map";import "@arcgis/map-components/components/arcgis-utility-network-trace-results-pane";import "@arcgis/map-components/components/arcgis-utility-network-trace-results";<calcite-shell> <calcite-shell-panel slot="panel-start" width-scale="l"> <calcite-panel heading="Compare trace results"> <arcgis-utility-network-trace-results-pane> <arcgis-utility-network-trace-results id="upstream-results" heading="Upstream trace" expandable expanded ></arcgis-utility-network-trace-results> <arcgis-utility-network-trace-results id="downstream-results" heading="Downstream trace" expandable expanded ></arcgis-utility-network-trace-results> </arcgis-utility-network-trace-results-pane> </calcite-panel> </calcite-shell-panel> <arcgis-map item-id="471eb0bf37074b1fbb972b1da70fb310" popup-disabled></arcgis-map></calcite-shell>Here, upstreamTraceResult and downstreamTraceResult are application-provided TraceResult objects, and utilityNetwork is the loaded network used to produce them. The web map must contain that network and its layers. Set the view and network on each Utility Network Trace Results component before assigning its trace result.
const mapElement = document.querySelector("arcgis-map");const comparisonPane = document.querySelector("arcgis-utility-network-trace-results-pane");const upstreamResults = document.getElementById("upstream-results");const downstreamResults = document.getElementById("downstream-results");const comparisonResults = [upstreamResults, downstreamResults];
await Promise.all([ mapElement.viewOnReady(), comparisonPane.componentOnReady(), ...comparisonResults.map((result) => result.componentOnReady()),]);
for (const result of comparisonResults) { result.view = mapElement.view; result.utilityNetwork = utilityNetwork; result.addEventListener("arcgisResultsReady", () => { console.log(result.heading, result.traceResultFeatures); });}
upstreamResults.traceResult = upstreamTraceResult;downstreamResults.traceResult = downstreamTraceResult;Each Utility Network Trace Results component displays its default result items and processes its result independently. Listen for arcgisResultsReady on each component before reading its queried features, as shown above.
If a trace fails in your workflow, assign its error to the corresponding component’s traceError; the other result can remain visible. Before replacing a displayed result, call clearResults() on that component to clear its previous result’s side effects.
Add custom drilldown content
The pane uses Calcite Flow, a container for navigating between related views with forward and back navigation. Use the pane’s flowItems collection to display application-specific content, such as a comparison summary or follow-up controls, without replacing the trace results.
The pane’s default slot appears in its root flow item, which is not part of flowItems. Adding a Calcite Flow Item to the collection opens a new view in front of the results. Users can navigate back to the results without rerunning the traces.
For example, add this button inside the Calcite Panel from the preceding example, using its footer slot:
<calcite-button id="show-trace-summary" slot="footer" width="full"> Show comparison summary</calcite-button>The following code reuses comparisonPane from that example:
import "@esri/calcite-components/components/calcite-button";import "@esri/calcite-components/components/calcite-flow-item";
const summaryButton = document.getElementById("show-trace-summary");await Promise.all([ comparisonPane.componentOnReady(), summaryButton.componentOnReady(),]);
const summaryItem = document.createElement("calcite-flow-item");summaryItem.heading = "Comparison summary";
const summary = document.createElement("p");summary.textContent = "Review the upstream and downstream results before choosing a follow-up action.";summaryItem.append(summary);
summaryButton.addEventListener("click", () => { comparisonPane.flowItems.add(summaryItem); summaryButton.disabled = true;});
summaryItem.addEventListener("calciteFlowItemBack", () => { comparisonPane.flowItems.remove(summaryItem); summaryButton.disabled = false;});The back handler removes the custom flow item from the collection so the trace results are visible again. Although flowItems is a read-only property, its collection is mutable: use add() and remove() rather than replacing it. Call comparisonPane.flowItems.removeAll() to clear all custom flow items without removing the slotted Utility Network Trace Results components.
When adding custom views to the integrated Utility Network Trace Analysis interface instead, use Utility Network Trace Analysis.flowItems.
Customize feature actions
The trace components use the Features component to display candidate trace location features and trace result features. The actions property defines a collection of buttons or toggles that users click in the Features component action bar to perform a task. For example, the default Zoom To action centers the view on the selected feature and zooms in. You can add custom actions alongside the default actions to display while users inspect candidate trace locations or trace result features.
As with the Features component’s actions API, use ActionButton or ActionToggle objects to define custom actions. Each action’s title and icon describe its purpose, and actions appear in collection order. Adding an action defines the control, not its behavior: handle arcgisTriggerAction and check event.detail.action.id to perform the corresponding task. The event identifies the action; it does not include the inspected feature.
On Utility Network Trace Elements Result Item, use selectedResultFeature to access the feature currently being inspected.
Choose where to configure actions based on where users need them:
| Component | Where its custom actions appear |
|---|---|
| Utility Network Trace Analysis | Trace location selection and default elements result item. |
| Utility Network Trace Inputs | Trace location selection. |
| Utility Network Trace Results | Default elements result item. |
| Utility Network Trace Elements Result Item | Feature inspection in that elements result item. |
Example: Add an action to Utility Network Trace Analysis
Configure a custom action on Utility Network Trace Analysis and listen for its arcgisTriggerAction event. This example opens an application-provided asset reference panel from either input or result feature inspection.
Here, asset-reference is the ID of an existing application panel hidden with the HTML hidden attribute.
import Collection from "@arcgis/core/core/Collection.js";import ActionButton from "@arcgis/core/support/actions/ActionButton.js";
const traceAnalysis = document.querySelector("arcgis-utility-network-trace-analysis");const assetReference = document.getElementById("asset-reference");await traceAnalysis.componentOnReady();
traceAnalysis.actions = new Collection([ new ActionButton({ id: "open-asset-reference", title: "Open asset reference", icon: "information", }),]);
traceAnalysis.addEventListener("arcgisTriggerAction", (event) => { if (event.detail.action.id === "open-asset-reference") { assetReference.hidden = false; }});Example: Use different actions for inputs and results
In a custom trace workflow, configure Utility Network Trace Inputs and Utility Network Trace Results independently. For example, input actions can open location-selection guidance, while result actions can download feature attributes.
If you supply an elements result item in the Utility Network Trace Results component’s default slot, configure actions and handle arcgisTriggerAction directly on that child instead. It inherits the trace result, utility network, and view from its parent, but not the parent’s actions or hideActionBar. This also applies when the components are nested inside Utility Network Trace Analysis.
The following example assumes the inputs and results components already have their view and utility network context, as shown in the earlier examples, and that the results component contains a slotted Utility Network Trace Elements Result Item. The application provides a panel with ID trace-location-help, initially hidden with the HTML hidden attribute.
import Collection from "@arcgis/core/core/Collection.js";import ActionButton from "@arcgis/core/support/actions/ActionButton.js";import { downloadBlobAsFile } from "@arcgis/core/core/urlUtils.js";
const inputs = document.querySelector("arcgis-utility-network-trace-inputs");const elementsResultItem = document.querySelector("arcgis-utility-network-trace-elements-result-item");const locationHelp = document.getElementById("trace-location-help");await Promise.all([inputs.componentOnReady(), elementsResultItem.componentOnReady()]);
inputs.actions = new Collection([ new ActionButton({ id: "location-help", title: "Trace location help", icon: "question", }),]);
inputs.addEventListener("arcgisTriggerAction", (event) => { if (event.detail.action.id === "location-help") { locationHelp.hidden = false; }});
elementsResultItem.actions = new Collection([ new ActionButton({ id: "download-attributes", title: "Download feature attributes", icon: "download", }),]);
elementsResultItem.addEventListener("arcgisTriggerAction", (event) => { if (event.detail.action.id === "download-attributes") { const feature = elementsResultItem.selectedResultFeature; const blob = new Blob([JSON.stringify(feature.attributes, null, 2)], { type: "application/json", }); downloadBlobAsFile(blob, "feature-attributes.json"); }});The elements result item’s selectedResultFeature identifies the feature currently being inspected, including an associated feature opened through drilldown. This example downloads that feature’s attributes, not the entire trace response.
To hide the feature action bar, set hideActionBar on the same component where you configure actions. For example, on Utility Network Trace Analysis or Utility Network Trace Elements Result Item.
To hide only the default actions while retaining your custom actions, set includeDefaultActionsDisabled to true on the same component, such as Utility Network Trace Analysis or Utility Network Trace Elements Result Item.