How to scale marker size based on zoom?

1864
2
Jump to solution
04-18-2021 11:46 AM
Neocyte
New Contributor II

I am creating a viewshed analysis application using ArcGIS' Viewshed Sample. My application involves placing multiple markers at specific locations and computing each marker's viewshed on load:

 

function drawResultData(result) {
          var resultFeatures = result.results[0].value.features;

          // Assign each resulting graphic a symbol
          var viewshedGraphics = resultFeatures.map(function(feature) {
            feature.symbol = fillSymbol;
            return feature;
          });

          // Add the resulting graphics to the graphics layer
          graphicsLayer.addMany(viewshedGraphics);

 

The ArcGIS JS API has an example of scaling markers based on zoom, but it uses a SimpleRenderer that is passed into a FeatureLayer. Unfortunately, my application only uses GraphicsLayers, which do not support renderers.

Is there a way to make Graphics on a GraphicsLayer scale based on zoom? If not, how could I modify the viewshed sample to use a FeatureLayer instead? 

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
UndralBatsukh
Esri Regular Contributor

Hi there, 

You can use client-side FeatureLayer to achieve what you are asking. This sample shows you how to create a client-side feature layer and add/remove features from it at runtime with the use of FeatureLayer.applyEdits

In any case, this is the workflow you can have. 

1. Initialize an empty feature collection as shown below:

const layer = new FeatureLayer({
  fields: [
    {
      name: "ObjectID",
      alias: "ObjectID",
      type: "oid"
     },
     {
       name: "Name",
       alias: "Name",
       type: "string"
      },
      {
        name: "Type",
        alias: "Type",
        type: "string"
      }
  ],
  objectIdField: "ObjectID",
  geometryType: "point", // =>>> MATCH THE GEOMETRY TYPE
  spatialReference: { wkid: 4326 },
  source: [], // adding an empty feature collection
  renderer: {   // =>>> MATCH THE RENDERER TYPE
    type: "simple",
    symbol: {
      type: "web-style", //  =>>> MATCH THE SYMBOL TYPE
      styleName: "Esri2DPointSymbolsStyle",
      name: "landmark"
    }
  },
  popupTemplate: {
    title: "{Name}"
  }
 });

 

2. Then once you have the resultFeatures, use FeatureLayer.applyEdits to add the features. 

const addEdits = {
  addFeatures: graphics
};
layer.applyEdits(addEdits).then(function(results) {
  // feature are added... Now you can query the features
})
.catch(function(error){
 // apply edits error
});

 

Hope this helps,

-Undrral

View solution in original post

2 Replies
UndralBatsukh
Esri Regular Contributor

Hi there, 

You can use client-side FeatureLayer to achieve what you are asking. This sample shows you how to create a client-side feature layer and add/remove features from it at runtime with the use of FeatureLayer.applyEdits

In any case, this is the workflow you can have. 

1. Initialize an empty feature collection as shown below:

const layer = new FeatureLayer({
  fields: [
    {
      name: "ObjectID",
      alias: "ObjectID",
      type: "oid"
     },
     {
       name: "Name",
       alias: "Name",
       type: "string"
      },
      {
        name: "Type",
        alias: "Type",
        type: "string"
      }
  ],
  objectIdField: "ObjectID",
  geometryType: "point", // =>>> MATCH THE GEOMETRY TYPE
  spatialReference: { wkid: 4326 },
  source: [], // adding an empty feature collection
  renderer: {   // =>>> MATCH THE RENDERER TYPE
    type: "simple",
    symbol: {
      type: "web-style", //  =>>> MATCH THE SYMBOL TYPE
      styleName: "Esri2DPointSymbolsStyle",
      name: "landmark"
    }
  },
  popupTemplate: {
    title: "{Name}"
  }
 });

 

2. Then once you have the resultFeatures, use FeatureLayer.applyEdits to add the features. 

const addEdits = {
  addFeatures: graphics
};
layer.applyEdits(addEdits).then(function(results) {
  // feature are added... Now you can query the features
})
.catch(function(error){
 // apply edits error
});

 

Hope this helps,

-Undrral

KristianEkenes
Esri Regular Contributor

> Is there a way to make Graphics on a GraphicsLayer scale based on zoom?

No. There is no way to efficiently scale the symbols of graphics in the view graphics or in a GraphicsLayer.

> If not, how could I modify the viewshed sample to use a FeatureLayer instead? 

You will need to create a client-side feature layer and add a simple renderer to it using the code in the sample you referenced above. Undral's comment shows how you can create a feature layer using graphics. If this is only to display temporary results in the view, you can just construct the FeatureLayer and pass the graphics to the layer.source. When you want to clear the graphics, destroy the layer. That way you avoid using applyEdits. 

The method of managing the graphics with applyEdits or creating a new layer every time is up to you.