Select to view content in your preferred language

Toggling `labelsVisible` renders the same label multiple times

1464
2
Jump to solution
01-22-2024 10:45 PM
seanodon
New Contributor

Hi folks,

When toggling the `labelsVisible` property on a SceneView's FeatureLayer, it correctly hides the labels when set to false but when setting back to true the labels appear to be rendering multiple times on top of each other. Only noticed this behaviour because we use a semi-transparent background for our labels, which becomes opaque after the labels get drawn multiple times.

I've adapted one of the samples to demonstrate the behaviour:

<html lang="en">

<head>
  <meta charset="utf-8" />
  <title>Using callout lines with labels | Sample | ArcGIS Maps SDK for JavaScript 4.28</title>

  <script type="module" src="https://js.arcgis.com/calcite-components/1.9.2/calcite.esm.js"></script>
  <link rel="stylesheet" type="text/css" href="https://js.arcgis.com/calcite-components/1.9.2/calcite.css" />

  <link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/light/main.css" />
  <script src="https://js.arcgis.com/4.28/"></script>

  <style>
    html,
    body,
    #viewDiv {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
    }

    #toggleView {
      position: absolute;
      width: 200px;
      bottom: 40px;
      left: 50%;
      margin-left: -100px;
    }

    #titleDiv {
      padding: 20px;
      font-size: 18pt;
      font-family: "Belleza", sans-serif;
      text-align: center;
      background-color: rgb(255, 255, 255, 1);
      border-radius: 7px;
    }
  </style>

  <script>
    require(["esri/WebScene", "esri/layers/FeatureLayer", "esri/views/SceneView"], (
      WebScene,
      FeatureLayer,
      SceneView,

    ) => {

      /***********************************
       * Load Scene and create a SceneView
       ***********************************/
      // Create view and load an existing webscene into it
      const webscene = new WebScene({
        portalItem: {
          // autocasts as new PortalItem()
          id: "ac98048566114b83807f8e0aec9332a4"
        }
      });

      const view = new SceneView({
        container: "viewDiv",
        map: webscene,
        qualityProfile: "high",
        environment: {
          lighting: {
            directShadowsEnabled: true,
          }
        }
      });

      const labelClasses = [
        { above: 4000, fontSize: 14 },
        { above: 3000, fontSize: 12 },
        { above: 2000, fontSize: 10 }
      ];

      // Create layer with the mountain peaks
      const peaks = new FeatureLayer({
        url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/AlpineSummits/FeatureServer",
        elevationInfo: {
          mode: "relative-to-ground"
        },
        returnZ: false,
        screenSizePerspectiveEnabled: false,
        // Set a renderer that will show the points with icon symbols
        renderer: {
          type: "simple", // autocasts as new SimpleRenderer()
          symbol: {
            type: "point-3d", // autocasts as new PointSymbol3D()
            symbolLayers: [
              {
                type: "icon", // autocasts as new IconSymbol3DLayer()
                resource: {
                  primitive: "circle"
                },
                material: {
                  color: "black"
                },
                size: 4
              }
            ]
          }
        },
        outFields: ["*"],

        // Add labels with callouts of type line to the icons
        labelingInfo: labelClasses.map(({ above, fontSize }) =>
          ({
            // autocasts as new LabelClass()
            labelPlacement: "above-center", // When using callouts on labels, "above-center" is the only allowed position
            labelExpressionInfo: {
              expression: `$feature.NAME + TextFormatting.NewLine + Text($feature.HOEHE, "#,### m")`
            },
            where: "HOEHE > " + above, // The scene view picks the first label class that satisfies this condition
            symbol: {
              type: "label-3d", // autocasts as new LabelSymbol3D()
              symbolLayers: [
                {
                  type: "text", // autocasts as new TextSymbol3DLayer()
                  material: { color: "black" },
                  background: { color: [0,0,0,0.5] },
                  halo: {
                    color: [255, 255, 255, 0.7],
                    size: 1.2
                  },
                  font: {
                    family: "Belleza" // This font will be loaded from https://static.arcgis.com/fonts
                  },
                  size: fontSize // Larger font sizes will be prioritized when deconflicting labels
                }
              ],
              // Labels need a small vertical offset that will be used by the callout
              verticalOffset: {
                screenLength: 75,
                maxWorldLength: 1000,
                minWorldLength: 30
              },
              // The callout has to have a defined type (currently only line is possible)
              // The size, the color and the border color can be customized
              callout: {
                type: "line", // autocasts as new LineCallout3D()
                size: 0.5,
                color: [0, 0, 0],
                border: {
                  color: [255, 255, 255, 0.7]
                }
              }
            }
          })
        )
      });

      webscene.add(peaks);

      // Make the button toggle between top-down and bird eye's view
      const button = document.getElementById("toggleView");
      button.addEventListener("click", () => {
        peaks.labelsVisible = !peaks.labelsVisible;
      });

      // Add the title to the map
      view.ui.add("titleDiv", "top-right");

    });
  </script>
</head>

<body>
  <div id="viewDiv" class="esri-widget"></div>
  <calcite-button id="toggleView">Toggle labelsVisible</calcite-button>
  <div id="titleDiv">Peaks higher than 2,500 m</div>
</body>

</html>

 

Am I misusing the property or is this a bug? Is there a way I can programmatically hide/show the labels that doesn't cause this behaviour?

Thanks

0 Kudos
1 Solution

Accepted Solutions
SaschaBrunnerCH
Esri Contributor

Hi 
Thanks for reporting with a sample to demonstrate it. This is a bug. We are working on it to fix.
The workaround for now is only using non semi-transparent background.
Thanks

View solution in original post

2 Replies
SaschaBrunnerCH
Esri Contributor

Hi 
Thanks for reporting with a sample to demonstrate it. This is a bug. We are working on it to fix.
The workaround for now is only using non semi-transparent background.
Thanks

seanodon
New Contributor

That's great, thank you for the confirmation - I'll keep an eye out for the fix.

Cheers.

0 Kudos