3

I'm trying to write a handler for a mouse-over event on a FeatureLayer in ArcGIS JS API 4.4. It seems in the previous API this was built in, but I'm not finding it anywhere in the new API. Am I missing something or was this just lost in the overhaul? If so, is there a workaround?

This thread mentions an option but the link doesn't take you there, I'm guessing this was for the old API.

1 Answer 1

2

You have to use hitTest for this type of interaction. There's a discussion on GeoNet that shows how to do this, using this code:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="description" content="[Access features with click events - 4.3]">
<!--
ArcGIS API for JavaScript, https://js.arcgis.com
For more information about the view-hittest sample, read the original sample description at developers.arcgis.com.
https://developers.arcgis.com/javascript/latest/view-hittest/index.html
-->
<title>Access features with click events - 4.3</title>

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

#info {
  background-color: black;
  opacity: 0.75;
  color: orange;
  font-size: 18pt;
  padding: 8px;
  visibility: hidden;
}
</style>

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

<script>
require([
  "esri/core/watchUtils",
  "esri/Map",
  "esri/views/MapView",
  "esri/layers/FeatureLayer",
  "esri/renderers/UniqueValueRenderer",
  "esri/symbols/SimpleLineSymbol",
  "dojo/dom",
  "dojo/domReady!"
], function(
  watchUtils,
  Map,
  MapView,
  FeatureLayer,
  UniqueValueRenderer,
  SimpleLineSymbol,
  dom
) {

  var layer = new FeatureLayer({
    url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Hurricanes/MapServer/1",
    outFields: ["*"]
  });

  var map = new Map({
    basemap: "dark-gray",
    layers: [layer]
  });

  var view = new MapView({
    container: "viewDiv",
    map: map,
    center: [-61.125537, 35.863534],
    zoom: 4
  });

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


  function changeCursor(response){
    if (response.results.length > 0){
      document.getElementById("viewDiv").style.cursor = "pointer";
    } else {
      document.getElementById("viewDiv").style.cursor = "default";
    }
  }

  function getGraphics(response) {
    // the topmost graphic from the click location
    // and display select attribute values from the
    // graphic to the user
    var graphic = response.results[0].graphic;
    var attributes = graphic.attributes;
    var category = attributes.CAT;
    var wind = attributes.WIND_KTS;
    var name = attributes.NAME;

    dom.byId("info").style.visibility = "visible";
    dom.byId("name").innerHTML = name;
    dom.byId("category").innerHTML = "Category " + category;
    dom.byId("wind").innerHTML = wind + " kts";

    // symbolize all line segments with the given
    // storm name with the same symbol
    var renderer = new UniqueValueRenderer({
      field: "NAME",
      defaultSymbol: layer.renderer.symbol || layer.renderer.defaultSymbol,
      uniqueValueInfos: [{
        value: name,
        symbol: new SimpleLineSymbol({
          color: "orange",
          width: 5,
          cap: "round"
        })
      }]
    });
    layer.renderer = renderer;
  }

  view.then(function() {
    view.whenLayerView(layer).then(function(lview) {
      watchUtils.whenFalseOnce(lview, "updating", function(){
        // Set up a click event handler and retrieve the screen x, y coordinates 
        view.on("pointer-move", function(evt) {
            var screenPoint = {
              x: evt.x,
              y: evt.y
            };

            // the hitTest() checks to see if any graphics in the view
            // intersect the given screen x, y coordinates
            view.hitTest(screenPoint)
              .then( function(response){
                changeCursor(response);
                getGraphics(response);
              });      
        });
      });
    });
    layer.then(function() {
      // update the default renderer's
      // symbol when the layer loads
      var renderer = layer.renderer.clone();
      renderer.symbol.width = 4;
      renderer.symbol.color = [128, 128, 128, 0.8];
      renderer.symbol.cap = "round";
      layer.renderer = renderer;
    });
  });
});
</script>
</head>

<body>
<div id="viewDiv"></div>
<div id="info">
<span id="name"></span><br>
<span id="category"></span><br>
<span id="wind"></span>
</div>
</body>

</html>
1
  • Yes it looks like the View object contains a "pointer-move" event which MapView inherits. Commented Sep 15, 2017 at 14:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.