Intro to SubtypeGroupLayer

Explore in the sandboxView live

This sample demonstrates how to add a SubtypeGroupLayer to a Map. The data in this sample comes from an electic utility network dataset to highlight how utility network datasets can take advantage of the SubtypeGroupLayer's features.

How it works

The SubtypeGroupLayer automatically creates a sublayer, known as a SubtypeSublayer, from each subtype in its corresponding feature service. The purpose of this is to treat each subtype in a feature service as its own layer. By treating each subtype as its own layer, we can then configure a renderer, popup, and labels for each sublayer.

This sample illustrates a workflow to configure 13 sublayers using LayerList widget actions. Keep in mind that this data source is a single feature service, so it is fascinating that we will be able to configure 13 sublayers out of a single layer.

First, let us initialize the SubtypeGroupLayer and add it to the Map.

          
1
2
3
4
5
6
7
8
9
10
// initializing a SubtypeGroupLayer
// creating the SubtypeGroupLayer from a feature service url will also work
const stgl = new SubtypeGroupLayer({
  portalItem: {  // autocasts as new PortalItem()
    id: "b702d7258a724a53aada3fefc3a36829"
  },
  outFields: ["assettype", "assetgroup", "objectid", "transformer_kva", "subnetworkname"]
});

map.add(stgl);

Note

In order to use the SubtypeGroupLayer, the data source you publish must be published as a SubtypeGroupLayer. To learn more about how to create a SubtypeGroupLayer using ArcGIS Pro, please read the following documentation.

Using LayerList actions for SubtypeSublayer property controls

With this sample, we will take advantage of the LayerList widget actions to add toggles for labels and renderers for each sublayer. More specifically, we will use the listItemCreatedFunction property of the LayerList to add toggle buttons for each ListItem in the widget. Each ListItem will represent a SubtypeSublayer displayed in the view.

                  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
view.when(() => {
  let index = 0;  // tracking index of the layer items

  // initializing the LayerList widget
  const layerList = new LayerList({
    view: view,
    listItemCreatedFunction(event) {
      // this executes for each ListItem in the LayerList
      if (event.item.layer.type === "subtype-sublayer") {
        // set the layer properties and UI for each sublayer
        setLayerListActions(event.item, index++);
      }
    }
  })

  // add the widget to the view
  view.ui.add(layerList, "top-right");
});

The following function handles configuring the layer properties of a sublayer, and adding the UI toggles. The UI consists of two buttons; one button to toggle the labels, and the other to toggle the renderer.

                                      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// set the sublayer properties and
// create the UI for the LayerList actions
function setLayerListActions(item, index) {
  // set labels for each sublayer
  item.layer.labelingInfo = [labelClass];
  item.layer.labelsVisible = false;

  // set a PopupTemplate for each sublayer
  item.layer.popupTemplate = popupTemplate;

  // creating the LayerList actions UI
  const blockDiv = document.createElement('div');
  blockDiv.classList.add('btn-group');

  // create a labels toggle button
  const labelsBtn = document.createElement('button');
  labelsBtn.innerText = "Labels";
  labelsBtn.onclick = () => { setLabels(item.layer, labelsBtn) };
  blockDiv.appendChild(labelsBtn);

  // create renderer toggle button
  const rendererBtn = document.createElement('button');
  setBtnUI(rendererBtn, "simple", "#000000", "#CC99FF");
  rendererBtn.onclick = () => { setRenderer(item.layer, rendererBtn) };
  blockDiv.appendChild(rendererBtn);

  // set layerlist actions
  item.panel = {
    content: blockDiv,
    className: "esri-icon-settings"
  }
  // setting the first sublayer action panel
  // as open by default
  if (index === 0) {
    item.panel.open = true;
    defaultRenderer = item.layer.renderer;
  }
}

Updating the Renderer

The code in the sample allows users to toggle between a SimpleRenderer, ClassBreaksRenderer, and a UniqueValueRenderer. This highlights how the SubtypeSublayer supports different types of renderers.

                     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// handles the renderer toggle logic
function setRenderer(sublayer, btn) {
  // if using simple renderer then set the next
  // renderer as class-breaks
  if (sublayer.renderer.type === "simple") {
    sublayer.renderer = classBreaksRenderer;
    setBtnUI(btn, "unique-value", "#000000", "#F4A896");
  }
  // if using class-breaks, the next renderer is
  // unique-value - sublayer's default renderer is unique-value
  else if (sublayer.renderer.type === "class-breaks") {
    sublayer.renderer = defaultRenderer;
    setBtnUI(btn, "simple", "#000000", "#CC99FF");
  }
  // if using unique-value renderer then set the next
  // renderer to a simple renderer
  else if (sublayer.renderer.type === "unique-value") {
    sublayer.renderer = simpleRenderer;
    setBtnUI(btn, "class-breaks", "#FFFFFF", "#358597");
  }
}

Known Limitations

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.