How to highlight feature A and B whenever one is hovered? Streets and Streetname

498
2
Jump to solution
06-24-2020 06:01 AM
ChristianBischof
Esri Contributor

Hey guys!

I have a problem with a functionality we'd like to achieve. We have a map with two FeatureLayers (Streets of a Country, Streetsnumber). Streets of a country has a SimpleRenderer and displays lines on a 2D Map containing the streets in that country and the Streetsnumber has a UniqueValueRenderer displaying a png image with the street number in it somewhere on the streets.

What I'd like to achieve is that the png image gets increased in size whenever the user hovers over the exact image AND if the user hovers somewhere over the street the image represents. For example if the user hovers the Route 66, the png (which is located somewhere on the Route 66) shoult increase in size and decrease if the hover is over.

Right now we've made it to the point that the streets gets highlighted and the street png as soon as the user hovers it, but it should increase before it gets hovered - right when the street itself is hovered. See attachments.

flnumber -> feature layer with the numbers on the map

flstreets -> freature layer with the street lines on the map

using JS API 4.15

view
.when()
.then(function () {
  return flstreets.when();
})
.then(function (layer) {

  return view.whenLayerView(layer);
})
.then(function (layerView) {
  view.on("pointer-move", eventHandler);

  function eventHandler(event) {
    // the hitTest() checks to see if any graphics in the view
    // intersect the x, y coordinates of the pointer
    view.hitTest(event).then(getGraphics_Move);
  }

  var highlight, currentName;

  function getGraphics_Move(response) {
    // the topmost graphic from the flstreets
    // and display select attribute values from the
    // graphic to the user
    var graphic_railway, name, targetnum, graphic_number;
    var tooltip = document.getElementById("nametooltip");
    if (response.results.length) {
      //railwaygraphic

      try {
        graphic_railway = response.results.filter(function (result) {
          return result.graphic.layer === flstreets;
        })[0].graphic;
        console.log(graphic_railway)

        name = graphic_railway.attributes.Bezeichnun;
        targetnum = indexrenderer.indexOf(name);

        try {
          graphic_number = response.results.filter(function (result) {
            return result.graphic.layer === flnumber;
          })[0].graphic;

          var rend = graphic_number.layer.renderer.clone(); //rend temporary huge renderer
          for (var r = 0; r < rend.uniqueValueInfos.length; r++) {
            if (rend.uniqueValueInfos[r].label === name) {
              rend.uniqueValueInfos[r].symbol.width = 33;
              rend.uniqueValueInfos[r].symbol.height = 33;
              graphic_number.layer.renderer = rend;
              break;
            }
          }
        } catch {
          console.log("info: no number graphic");
        }

        function controlTooltip(name, e) {
          if (currentName == name) {
            var name = name;
            //prevent tooltip from "wiggling" around by only changing the x and y values whenever a new feature is hovered
            tooltip.style.top = "" + e.y + "px";
            tooltip.style.left = "" + e.x + "px";
            tooltip.style.display = "inline-block";
            tooltip.style.visibility = "visible";
            tooltip.style.position = "absolute";
            tooltip.style.backgroundColor = "#fff";
            tooltip.style.padding = "10px";
            tooltip.style.borderRadius = "5px";
            tooltip.style.fontFamily = "sans-serif";
            tooltip.style.fontWeight = "bold";
            tooltip.style.boxShadow = "2px 2px 1px #88888888";
            tooltip.innerHTML = name;
            currentName = name;
          }
        }

        controlTooltip(name, response.screenPoint);
      } catch {
        console.log("Info: graphic is " + typeof graphic);
      }

      if (highlight && currentName !== name) {
        flnumber.renderer = newrenderer; //set back to original renderer
        tooltip.style.display = "none";
        tooltip.style.visibility = "hidden";
        highlight.remove();
        highlight = null;
        return;
      }

      if (highlight) {
        return;
      }

      // highlight all features belonging to the same railway as the feature
      // returned from the hitTest
      var query = layerView.createQuery();
      query.where = "Bezeichnun = '" + name + "'";
      layerView.queryObjectIds(query).then(function (ids) {
        if (highlight) {
          highlight.remove();
        }
        highlight = layerView.highlight(ids);
        currentName = name;
      });
    } else {
      // remove the highlight if no features are
      // returned from the hitTest
      if (highlight) {
        flnumber.renderer = newrenderer; //set back to original renderer
        tooltip.style.display = "none";
        tooltip.style.visibility = "hidden";
        highlight.remove();
        highlight = null;
      }
    }
  }
});
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

Christain,

   My suggestion would be to not attempt to change the renderer for the street number but to instead add the desired feature to the maps graphics layer with the size symbol that you are wanting and remove that graphic when the mouse leaves the feature.

View solution in original post

2 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Christain,

   My suggestion would be to not attempt to change the renderer for the street number but to instead add the desired feature to the maps graphics layer with the size symbol that you are wanting and remove that graphic when the mouse leaves the feature.

ChristianBischof
Esri Contributor

Thanks Robert Scheitlin, GISP‌ for your suggestion I was able to implement it! Here's a code snippet for all of you interested in how it works.

1) Highlight the streets on hover

2) Whenever this happens check the matching "Name" attributes of the streetsymbol and the street itself by applying queryFeatuers on the Streetssymbol FeatureLayer

3) Add the graphic with the matching symbol to the map

4) remove all graphics from graphicslayer before adding a new one

var graphicslayer = new GraphicsLayer();
map.add(graphicslayer);

function addNumberGraphic(feature, symbol){
      var numgraphic = new Graphic({
          attributes: feature.attributes,
          geometry: feature.geometry,
          symbol: symbol
          });
      // take the given symbol as "base symbol" and modify it to your needs
      numgraphic.symbol.width = 33;
      numgraphic.symbol.height = 33;
      graphicslayer.add(numgraphic);
}‍‍‍‍‍‍‍‍‍‍


streetsnumberlayer.queryFeatures().then(function(results){
      // check by attributes of feature layer if currentStreetname
      // matches the attribute Name of the feature
      // if yes
      graphicslayer.removeAll();
      addNumberGraphic(feature, symbol)
});‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍