4.x: Renderer: getSymbol() support dropped?

180
4
09-11-2019 07:33 PM
MichalGasparovic1
New Contributor III

Hi,

I'd like to know the reason behind dropping the support for the getSymbol() (Renderer | API Reference | ArcGIS API for JavaScript 3.29 )

It would be super helpful if we had the API that would retrieve me a symbol from any renderer class for the graphic/feature.

Scenario:

Identify/query task can get multiple features for different layers from mapservice(s). I would like to visualize the identified features on the map with their respective symbol from their own renderer. 

So ideally:

1) I would collect the rendering information from all the relevant mapservice layers

2) Instantiate the renderer classes based on the returned json from 1)

3) Perform my identify/query task

4) Get the symbols from for the results in 3) by using the renderer from step 2) via renderer.getSymbol(feature)

5) Provide the array of the features to the Popup via .features property

6) Hook onto the popup's select event and display the feature that is properly symbolized. In addition, I could add another symbol that would mimic the highlight from the mapview's highlightOptions property

Currently?

I identify the features, and then symbolize them with the same symbol (based on the geometry type of course).

Thanks

Tags (2)
0 Kudos
4 Replies
VictorTey
Esri Contributor

Hi, you can still access the symbol as part of the renderer object. It will be something like layer.renderer.defaultSymbol or something along that line.

0 Kudos
MichalGasparovic1
New Contributor III

Hi Victor, thanks for your response. 

defaultSymbol is ok if it's single value renderer. but class-breaks or unique-value is a different story as I need a relevant symbol based on the attributes.

I'm sure it's somewhere in the code already, why not just expose it so we have it available? .. unless there is another method I'm not aware of, but I'm asking because it's missing in the doco, and also, release notes 4.0 specifically say getSymbol() has been removed...

I get that you guys are pushing for feature layers to be used (and I'm all for it), but out-there in the real world there are still business requirements for the dynamic, cartographic-like mapservices that need to provide the query/identify functionality.

0 Kudos
ReneRubalcava
Frequent Contributor

There are a couple of methods on the renderers that could help with this.

UniqueValueRenderer
https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-UniqueValueRenderer.html#getUniqueValueInfo

ClassBreakRenderer
https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-ClassBreaksRenderer.htm...

Each one will return the symbol along with some extra information related to the renderer like the values and label.

You can use them like this.

view.on("click", (event) => {
params.geometry = event.mapPoint;
params.mapExtent = view.extent;
params.returnGeometry = true;

// pick the currently displayed sublayer
const index = Number(
selectElement.options[selectElement.selectedIndex].value
);
const subLayer = layer.findSublayerById(index);

identifyTask.execute(params).then((response) => {
response.results.forEach((result) => {
const graphic = result.feature.clone();
subLayer.renderer
.getClassBreakInfo(result.feature)
.then((info) => {
graphic.symbol = info.symbol.clone();
view.graphics.add(graphic);
})
.catch((error) => console.warn(error));
});
});
});‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

That should get you similar behavior to what you are looking for with getSymbol

Here is a live demo

https://codepen.io/odoe/pen/rNBKVve?editors=1000 

MichalGasparovic1
New Contributor III

Hi Rene, this is helpful, but not completely. You only have the renderer available for the subLayer because you specify it so in the code.

Now imagine you have a map service with around 80 sublayers (don't ask me why it's that many, not my domain). I cannot possibly hard-code that many renderers (and that wouldn't be a good solution either). If I try to implement your code above, the sublayer.renderer is null, I thought the .findSubLayerById() would also pull the render information automatically.

So I will have to pretty much end up with some custom functionality for getting the renderer for the sublayer from the server and store it in memory for future identify operations.

Thanks all for your help and for the codepen. I will try to update it to prove the 'zoom to layers in popup' doesnt work if the results are from the identify so you guys can have a look.

Cheers

0 Kudos