# Arcgis Widgets Advanced

> Add specialized widgets including BuildingExplorer, FloorFilter, Track, Locate, HistogramRangeSlider, ScaleBar, Compass, NavigationToggle, and media viewers. Use for building exploration, indoor mapping, GPS tracking, and data histograms.

- **Type:** Skill
- **Install:** `agentstack add skill-saschabrunnerch-arcgis-maps-sdk-js-ai-context-arcgis-widgets-advanced`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [SaschaBrunnerCH](https://agentstack.voostack.com/s/saschabrunnerch)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [SaschaBrunnerCH](https://github.com/SaschaBrunnerCH)
- **Source:** https://github.com/SaschaBrunnerCH/arcgis-maps-sdk-js-ai-context/tree/master/skills/arcgis-widgets-advanced

## Install

```sh
agentstack add skill-saschabrunnerch-arcgis-maps-sdk-js-ai-context-arcgis-widgets-advanced
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# ArcGIS Advanced Widgets

Use this skill for specialized and advanced widgets including building exploration, indoor mapping, device GPS tracking, navigation aids, histograms, and media viewing.

> **Related skills:** See `arcgis-widgets-ui` for basic widgets (Legend, LayerList, Search, etc.) and `arcgis-map-tools` for measurement, print, directions, and swipe tools.

## Import Patterns

### Direct ESM Imports

```javascript
import Track from "@arcgis/core/widgets/Track.js";
import Locate from "@arcgis/core/widgets/Locate.js";
import ScaleBar from "@arcgis/core/widgets/ScaleBar.js";
import Compass from "@arcgis/core/widgets/Compass.js";
import NavigationToggle from "@arcgis/core/widgets/NavigationToggle.js";
import HistogramRangeSlider from "@arcgis/core/widgets/HistogramRangeSlider.js";
import BuildingExplorer from "@arcgis/core/widgets/BuildingExplorer.js";
import FloorFilter from "@arcgis/core/widgets/FloorFilter.js";
```

### Dynamic Imports (CDN)

```javascript
const Track = await $arcgis.import("@arcgis/core/widgets/Track.js");
const Locate = await $arcgis.import("@arcgis/core/widgets/Locate.js");
const ScaleBar = await $arcgis.import("@arcgis/core/widgets/ScaleBar.js");
```

## Component Overview

| Component                        | Widget Class          | Purpose                                        |
| -------------------------------- | --------------------- | ---------------------------------------------- |
| `arcgis-building-explorer`       | BuildingExplorer      | Explore building scene layers                  |
| `arcgis-floor-filter`            | FloorFilter           | Filter indoor maps by floor                    |
| `arcgis-oriented-imagery-viewer` | OrientedImageryViewer | View oriented imagery                          |
| `arcgis-video-player`            | VideoPlayer           | Play video service feeds                       |
| `arcgis-track`                   | Track                 | Track device GPS location                      |
| `arcgis-locate`                  | Locate                | Zoom to user location                          |
| `arcgis-scale-bar`               | ScaleBar              | Display map scale bar                          |
| `arcgis-compass`                 | Compass               | Show north orientation                         |
| `arcgis-navigation-toggle`       | NavigationToggle      | Switch between pan and rotate                  |
| —                                | HistogramRangeSlider  | Histogram with range selection (Core API only) |

## BuildingExplorer

Explore and filter BuildingSceneLayer data by disciplines and categories. Works only in 3D SceneView.

### BuildingExplorer Component

```html

  

  import BuildingSceneLayer from "@arcgis/core/layers/BuildingSceneLayer.js";

  const sceneElement = document.querySelector("arcgis-scene");
  await sceneElement.viewOnReady();

  const buildingLayer = new BuildingSceneLayer({
    url: "https://tiles.arcgis.com/tiles/V6ZHFr6zdgNZuVG0/arcgis/rest/services/BSL__4326__United_States__NewYork__702702_702_Main/SceneServer",
  });

  sceneElement.map.add(buildingLayer);

```

### BuildingExplorer Widget (Core API)

```javascript
import BuildingExplorer from "@arcgis/core/widgets/BuildingExplorer.js";
import BuildingSceneLayer from "@arcgis/core/layers/BuildingSceneLayer.js";

const buildingLayer = new BuildingSceneLayer({
  url: "https://tiles.arcgis.com/tiles/V6ZHFr6zdgNZuVG0/arcgis/rest/services/BSL__4326__United_States__NewYork__702702_702_Main/SceneServer",
});

map.add(buildingLayer);

const buildingExplorer = new BuildingExplorer({
  view: view,
  layers: [buildingLayer],
});

view.ui.add(buildingExplorer, "top-right");
```

### BuildingExplorer with External Reference

```html

  
    
      
    
  

  

```

## FloorFilter

Filter floor-aware web maps by facility and floor level. Requires a floor-aware web map.

### FloorFilter Component

```html

  

```

### FloorFilter Widget (Core API)

```javascript
import FloorFilter from "@arcgis/core/widgets/FloorFilter.js";
import WebMap from "@arcgis/core/WebMap.js";

const webMap = new WebMap({
  portalItem: { id: "YOUR_FLOOR_AWARE_WEBMAP_ID" },
});

const view = new MapView({
  container: "viewDiv",
  map: webMap,
});

await view.when();

const floorFilter = new FloorFilter({ view: view });
view.ui.add(floorFilter, "top-left");
```

### FloorFilter Events

```javascript
import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js";

reactiveUtils.watch(
  () => floorFilter.level,
  (level) => console.log("Selected level:", level),
);

reactiveUtils.watch(
  () => floorFilter.facility,
  (facility) => console.log("Selected facility:", facility),
);
```

## OrientedImageryViewer

View and navigate oriented imagery captured in the field. Requires an OrientedImageryLayer.

### OrientedImageryViewer Component

```html

  

  import OrientedImageryLayer from "@arcgis/core/layers/OrientedImageryLayer.js";

  const viewElement = document.querySelector("arcgis-map");
  const viewer = document.querySelector("arcgis-oriented-imagery-viewer");

  await viewElement.viewOnReady();

  const oiLayer = new OrientedImageryLayer({
    url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/OrientedImagery/MapServer/0",
  });

  viewElement.map.add(oiLayer);
  viewer.layer = oiLayer;

```

### OrientedImageryViewer Widget (Core API)

```javascript
import OrientedImageryViewer from "@arcgis/core/widgets/OrientedImageryViewer.js";
import OrientedImageryLayer from "@arcgis/core/layers/OrientedImageryLayer.js";

const oiLayer = new OrientedImageryLayer({
  url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/OrientedImagery/MapServer/0",
});

map.add(oiLayer);

const viewer = new OrientedImageryViewer({
  view: view,
  layer: oiLayer,
});

view.ui.add(viewer, "top-right");
```

## VideoPlayer

Play video feeds from a VideoLayer service. Requires a VideoLayer.

### VideoPlayer Component

```html

  

  import VideoLayer from "@arcgis/core/layers/VideoLayer.js";

  const viewElement = document.querySelector("arcgis-map");
  const videoPlayer = document.querySelector("arcgis-video-player");

  await viewElement.viewOnReady();

  const videoLayer = new VideoLayer({
    url: "https://your-server.com/arcgis/rest/services/VideoService/MapServer/0",
  });

  viewElement.map.add(videoLayer);
  videoPlayer.layer = videoLayer;

```

## Track

Track the user's device GPS location in real time. Requires HTTPS and user permission.

### Track Component

```html

  
  

```

### Track Widget (Core API)

```javascript
import Track from "@arcgis/core/widgets/Track.js";
import Graphic from "@arcgis/core/Graphic.js";

const track = new Track({
  view: view,
  useHeadingEnabled: true,
  goToOverride: (view, options) => {
    options.target.scale = 1500;
    return view.goTo(options.target);
  },
});

view.ui.add(track, "top-left");
track.start();
```

### Track Events

```javascript
track.on("track", (event) => {
  const { position } = event;
  console.log("Lat:", position.coords.latitude);
  console.log("Lon:", position.coords.longitude);
  console.log("Accuracy:", position.coords.accuracy);
});

track.on("track-error", (event) => {
  console.error("Tracking error:", event.error);
});
```

### Track with Custom Symbol

```javascript
const track = new Track({
  view: view,
  graphic: new Graphic({
    symbol: {
      type: "simple-marker",
      size: 12,
      color: "blue",
      outline: { color: "white", width: 2 },
    },
  }),
});

view.ui.add(track, "top-left");
```

## Locate

Zoom to the user's current location. Single-action widget for finding device location.

### Locate Component

```html

  
  

```

### Locate Widget (Core API)

```javascript
import Locate from "@arcgis/core/widgets/Locate.js";

const locate = new Locate({
  view: view,
  useHeadingEnabled: false,
  goToOverride: (view, options) => {
    options.target.scale = 1500;
    return view.goTo(options.target);
  },
});

view.ui.add(locate, "top-left");
```

### Locate Events

```javascript
locate.on("locate", (event) => {
  console.log(
    "Located at:",
    event.position.coords.latitude,
    event.position.coords.longitude,
  );
});

locate.on("locate-error", (event) => {
  console.error("Location error:", event.error);
});
```

## ScaleBar

Display a scale bar indicator showing map scale.

### ScaleBar Component

```html

  

```

### ScaleBar Widget (Core API)

```javascript
import ScaleBar from "@arcgis/core/widgets/ScaleBar.js";

const scaleBar = new ScaleBar({
  view: view,
  unit: "dual", // "metric", "imperial", "dual", "non-metric"
  style: "line", // "line" or "ruler"
});

view.ui.add(scaleBar, "bottom-left");
```

## Compass

Display a compass indicator showing the current orientation.

### Compass Component

```html

  

  

```

### Compass Widget (Core API)

```javascript
import Compass from "@arcgis/core/widgets/Compass.js";

const compass = new Compass({ view: view });
view.ui.add(compass, "top-left");

// Clicking the compass resets rotation to north
// Programmatically reset:
view.rotation = 0; // 2D
view.goTo({ heading: 0 }); // 3D
```

## NavigationToggle

Switch between pan and rotate navigation modes. Primarily useful in 3D SceneView.

### NavigationToggle Component

```html

  

```

### NavigationToggle Widget (Core API)

```javascript
import NavigationToggle from "@arcgis/core/widgets/NavigationToggle.js";

const navigationToggle = new NavigationToggle({
  view: view,
  layout: "horizontal", // "horizontal" or "vertical"
});

view.ui.add(navigationToggle, "top-left");
```

## HistogramRangeSlider

Display a histogram with adjustable range slider handles for filtering data. Core API only.

### Basic HistogramRangeSlider

```javascript
import HistogramRangeSlider from "@arcgis/core/widgets/HistogramRangeSlider.js";
import * as histogram from "@arcgis/core/smartMapping/statistics/histogram.js";

const histogramResult = await histogram.histogram({
  layer: featureLayer,
  field: "population",
  numBins: 30,
});

const slider = new HistogramRangeSlider({
  bins: histogramResult.bins,
  min: histogramResult.minValue,
  max: histogramResult.maxValue,
  values: [histogramResult.minValue, histogramResult.maxValue],
  excludedBarColor: "#d7d7d7",
  rangeType: "between",
  container: "sliderDiv",
});
```

### HistogramRangeSlider with Layer Filtering

```javascript
const fieldName = "median_income";

const histogramResult = await histogram.histogram({
  layer: featureLayer,
  field: fieldName,
  numBins: 50,
});

const slider = new HistogramRangeSlider({
  bins: histogramResult.bins,
  min: histogramResult.minValue,
  max: histogramResult.maxValue,
  values: [histogramResult.minValue, histogramResult.maxValue],
  excludedBarColor: "#d7d7d7",
  rangeType: "between",
  labelFormatFunction: (value) => "$" + Math.round(value).toLocaleString(),
  container: "sliderDiv",
});

// Filter layer when slider values change
slider.on(["thumb-change", "thumb-drag", "segment-drag"], () => {
  const [min, max] = slider.values;
  featureLayer.definitionExpression = `${fieldName} >= ${min} AND ${fieldName} 
  
    
  

  
    
      
    
  

  
    
    
    
    
  

  import BuildingSceneLayer from "@arcgis/core/layers/BuildingSceneLayer.js";

  const sceneElement = document.querySelector("arcgis-scene");
  await sceneElement.viewOnReady();

  const buildingLayer = new BuildingSceneLayer({
    url: "https://tiles.arcgis.com/tiles/V6ZHFr6zdgNZuVG0/arcgis/rest/services/BSL__4326__United_States__NewYork__702702_702_Main/SceneServer",
  });

  sceneElement.map.add(buildingLayer);

```

### Indoor Mapping with Floor Filter

```html

  
  
  
  
  

```

### Navigation Widgets in 3D Scene

```html

  
  
  
  
  

```

## Reference Samples

- `building-scene-layer-explorer` - Exploring building scene layers
- `widgets-floorfilter` - Indoor floor filtering
- `layers-orientedimagerylayer` - Oriented imagery viewer
- `widgets-track` - GPS tracking widget
- `widgets-locate` - Locate widget
- `widgets-scalebar` - ScaleBar widget configuration
- `histogram-range-slider` - Histogram range slider for filtering

## Common Pitfalls

1. **Track widget requires HTTPS**: Track and Locate use the Geolocation API, which only works on HTTPS origins (or localhost). They fail silently on HTTP.

2. **FloorFilter needs floor-aware web map**: Requires a web map configured with floor-aware data including facility and level information. A standard web map will not display anything.

3. **BuildingExplorer only works with BuildingSceneLayer in SceneView**: Requires both a 3D SceneView (not MapView) and at least one BuildingSceneLayer. It will not work with other layer types or in 2D.

4. **HistogramRangeSlider needs valid bins**: The `bins` property must be an array of objects with `minValue`, `maxValue`, and `count` properties. Use `smartMapping/statistics/histogram` to generate valid bins from layer data.

5. **Missing reference-element on external components**: When placing widget components outside the map/scene element (e.g., in a Calcite panel), set the `reference-element` attribute to the map/scene element ID.

## Related Skills

- See `arcgis-widgets-ui` for basic UI widgets and Calcite integration
- See `arcgis-map-tools` for measurement, print, and routing tools
- See `arcgis-smart-mapping` for smart mapping statistics and histograms

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [SaschaBrunnerCH](https://github.com/SaschaBrunnerCH)
- **Source:** [SaschaBrunnerCH/arcgis-maps-sdk-js-ai-context](https://github.com/SaschaBrunnerCH/arcgis-maps-sdk-js-ai-context)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-saschabrunnerch-arcgis-maps-sdk-js-ai-context-arcgis-widgets-advanced
- Seller: https://agentstack.voostack.com/s/saschabrunnerch
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
