<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>SceneLayer filter and query | Sample | ArcGIS Maps SDK for JavaScript</title>
<!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
<script type="module" src="https://js.arcgis.com/5.0/"></script>
color: var(--calcite-color-text-2);
background-color: var(--calcite-color-foreground-1);
font-size: var(--calcite-font-size);
<arcgis-scene item-id="7685f7ba6b47426ea20d6f640cf98596">
<div id="optionsDiv" slot="top-left">
<b>Filter building by floor:</b>
<select id="floorSelect">
<option value="1=1">All</option>
<option value="FLOOR = '1'">1</option>
<option value="FLOOR = '2'">2</option>
<option value="FLOOR = '3'">3</option>
<arcgis-zoom slot="top-left"></arcgis-zoom>
<arcgis-navigation-toggle slot="top-left"></arcgis-navigation-toggle>
<arcgis-compass slot="top-left"> </arcgis-compass>
<arcgis-layer-list slot="top-right"></arcgis-layer-list>
<arcgis-legend slot="bottom-right"></arcgis-legend>
// Get a reference to the Scene
const viewElement = document.querySelector("arcgis-scene");
// Wait for the view to initialize
await viewElement.viewOnReady();
viewElement.environment.lighting.directShadowsEnabled = true;
// The field containing the building is different for each layer
// buildingQuery defines the query corresponding to each layer in the web scene
"Building Wireframe": "BUILDINGID = 'Q'",
"Interior Space": "BUILDING = 'Q'",
"Walls": "BUILDINGKEY = 'Q'",
"Doors": "BUILDINGKEY = 'Q'",
// Filter all layers in the web scene to contain only building Q
viewElement.map.layers.forEach((layer) => {
layer.definitionExpression = buildingQuery[layer.title];
// Preload the fields for filtering
viewElement.map.layers.forEach((layer) => {
if (layer.title !== "Building Wireframe") {
layer.outFields = ["FLOOR"];
// We will use the Interior Space layer many times, so we'll save it in a variable
const officeLayer = viewElement.map.layers.find((l) => {
return l.title === "Interior Space";
// The data set displays many types of offices, but below are the ones we want to display
// Function that calculates how many office types are currently shown and displays this in the legend
function displayOfficeTypes() {
// Create the query on the officeLayer so that it respects its definitionExpression
const query = officeLayer.createQuery();
query.outFields = ["SPACETYPE"];
// Query the officeLayer to calculate how many offices are from each type
officeLayer.queryFeatures(query).then((results) => {
const typesCounter = {}; // Counter for the office types defined in the officeTypes array
let othersCounter = 0; // Counter for all the other office types
// Count the types of all the features returned from the query
results.features.forEach((feature) => {
const spaceType = feature.attributes.SPACETYPE;
if (typesCounter[spaceType]) {
typesCounter[spaceType]++;
typesCounter[spaceType] = 1;
if (officeTypes.indexOf(spaceType) === -1) {
// To set the results in the legend, we need to modify the labels in the renderer
const newRenderer = officeLayer.renderer.clone();
officeTypes.forEach((value, i) => {
newRenderer.uniqueValueInfos[i].label =
value + ": " + (typesCounter[value] || 0) + " rooms";
newRenderer.defaultLabel = "Other types: " + othersCounter + " rooms";
officeLayer.renderer = newRenderer;
// Call the method to display the counts from each office type in the legend
// Function that will filter by the selected floor
function showFloors(event) {
// Retrieve the query stored in the selected value
const floorQuery = event.target.value;
// Update the definition expression of all layers except the wireframe layer
viewElement.map.layers.forEach((layer) => {
if (layer.title !== "Building Wireframe") {
layer.definitionExpression = buildingQuery[layer.title] + " AND " + floorQuery;
// After the layers were filtered recalculate the counts of each office type
document.getElementById("floorSelect").addEventListener("change", showFloors);
// Edit legend to only display the legend for the officeLayer
const legend = document.querySelector("arcgis-legend");
await legend.componentOnReady();