JSAPI 4.2 How exactly to set up visualVariables to generate univariate continuous size and color visualization in 3D

1690
4
Jump to solution
01-26-2017 09:27 AM
DavidChrest
Occasional Contributor II

So I love this great sample with the slider: Generate univariate continuous size and color visualization in 3D | ArcGIS API for JavaScript 4.2  and I want to do something just like this but instead using a simple schools wpoint FeatureLayer with number of students instead of cities with population like the sample shows.

So I add in my code essentially based just like the sample code but just switching out for my schools FeatureLayer. I then get this error: there was an error:  d {name: "size-visual-variable:insufficient-info", message: "Unable to find size scheme", details: undefined}.

Turns out I need to set up my visualVariables (and statistics too) inside the colorAndSizeRendererCreator.createContinuousRenderer(params):

 var sizeVV = response.size.visualVariable;
 var colorVV = response.color.visualVariable;

sliderParams.statistics = response.statistics;
sliderParams.visualVariables = [sizeVV, colorVV];‍‍‍‍‍

Turns out the FetureLayer in the sample has this all set up with "Drawing Info" in the FeatureLayer's service:

https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/Enriched%20World%20Cities/FeatureS... .

 So how do I set up these important statistics and visualVariables for my schools FeatureLayer by JS code. The snippets below the map in this sample page (Generate univariate continuous size and color visualization in 3D | ArcGIS API for JavaScript 4.2 ) are quite confusing.

Is this refereing to the assigned renderer in my renderer: property in my FeatureLayer?

// set the renderer to the layer povLyr.renderer = response.renderer;

Ande where exacttly atre these sizeVV and colorVV coming from? They are not set up in my rendere.

visualVariables: [ sizeVV, colorVV ]?

// size/color visual variables returned from createContinuousRenderer(),

There must be a straightforward code example to set up a common slider scenario with size, color, field max/min values, etc.  The set-up for the Thematic multivariate 3D visualization shows very well the symbolization syntax (Thematic multivariate visualization (3D) | ArcGIS API for JavaScript 4.2 ) for this slide example I'm pretty lost.

Any help is very much appreciated.

Much Thanks,

David

0 Kudos
1 Solution

Accepted Solutions
KristianEkenes
Esri Regular Contributor

The only thing I would really want to change programmatically is the min and max symbol size (the cylinders). Is there a way to adjust those properties?

The currently implementation uses the view to determine the min and max size so it varies depending on the scale of the view when the method is called. We're working on improving this so it is more consistent for 3D object symbols despite the scale.

However, if you want to change the min and max sizes, you can do that manually without the smart mapping modules, using the size visual variable. The smart mapping modules don't have to be used to work with the slider widgets though they are convenient for getting the stats and histogram. Here's an example of how to override the sizes after getting back the default renderer: JS Bin - Collaborative JavaScript Debugging 

Remember, these creator functions are all about giving you a good default, or starting point. You can visualize your data anyway you want to! But these modules help give you context if you're unfamiliar with your data or you want to allow others to explore it freely.

I'll take a look at the basemap issues. Note that note all vector tile basemaps will work. Only ones that have an equivalent raster basemap will generate a renderer. The reason for this is because the styles for smart mapping were designed before vector tiles came into the API. This is an issue we're aware of and looking to fix. In the meantime you can use the basemap string id of the basemap that most closely resembles whatever you are using that may be unsupported.

View solution in original post

0 Kudos
4 Replies
KristianEkenes
Esri Regular Contributor

Hi David,

The smartMapping API is all about generating a new renderer based on the statistics of your data. So the existing renderer on your service doesn't play a factor in this scenario. I'll try to go over the workflow as best I can. Please continue to ask questions if this is still confusing or if it's not exactly what you're looking for.

> Turns out the FetureLayer in the sample has this all set up with "Drawing Info" in the FeatureLayer's service:

https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/Enriched%20World%20Cities/FeatureS...

This drawingInfo is ignored in the sample. We want to generate a renderer on our own when the data loads. The renderer we generate will contain the visual variables you're looking for. So we call call colorAndSizeRendererCreator.createContinuousRenderer() to do this. The response object from this method also contains the visual variables conveniently so you don't have to search for specific ones in the renderer. To call the method, first set your params...

var params = {
    layer: povLyr, // your layer
    basemap: map.basemap,  // basemap to choose "best" color scheme
    field: "POP",  // field used to generate the visual variables
    view: view,  // the initial sizes are based on your current view (this will actually likely change in a future release)
    symbolType: "3d-volumetric",  // This indicates 3D object symbols will be used.
    minValue: 0  // this is optional
 };

 So how do I set up these important statistics and visualVariables for my schools FeatureLayer by JS code.

When the method resolves you can then grab the generated visual variables and statistics objects and set them in the slider widget. They are properties of the response object. See - univariateColorSize | API Reference | ArcGIS API for JavaScript 4.2 

colorAndSizeRendererCreator.createContinuousRenderer(params)
 .then(function(response) {
  // set generated renderer on the layer and add it to the map
  povLyr.renderer = response.renderer;
  map.add(povLyr);
  // set the queried statistics and generated visual variable
  // to the slider parameters
  
  var sizeVV = response.size.visualVariable;
  var colorVV = response.color.visualVariable;

  var sliderParams = {
    container: "sliderDiv",
    statistics: response.statistics,  // this is generated for you as well
    visualVariables: [sizeVV, colorVV]
  };
  
  var slider = new UnivariateColorSizeSlider(sliderParams);

 });‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The histogram is optional, but if you want to use that as well, then follow the example code you're looking at.

In short, you don't need visual variables on the default renderer on the layer for this to work. If you already have them, then you can use them without generating the renderer every time the app loads. in that case you could do something like the following:

layer.then(function(){
  var renderer = layer.renderer.clone();
   sliderParams = {
      container: "sliderDiv",
      visualVariables: renderer.visualVariables
      statistics: //stats object generated from summaryStatistics()
   };  
});

For the stats use: summaryStatistics | API Reference | ArcGIS API for JavaScript 4.2 

But if you use createContinuousRenderer() then this is already done for you under the hood.

There must be a straightforward code example to set up a common slider scenario with size, color, field max/min values, etc.

This is about as straightforward as it gets. If the snippets on the description page are confusing, then take look at the code in the sandbox. That should provide more context as to where the visual variables and statistics are coming from. We can also look at reworking that description so it doesn't cause as much confusion. I'll be working on a blog post going into a little more depth on this topic. Will link to it when it goes live.

Hope that helps!

DavidChrest
Occasional Contributor II

Hi Kristian,

Thanks for all these details! I did some investigating and it turns out I get this error when using the "streets-relief-vector" basemap in my SceneView:

d {name: "size-visual-variable:insufficient-info", message: "Unable to find size scheme", details: undefined}.

But it works wonderfully if I use the "topo" basemap. Yes, this is very straightforward and love all the under the hood action here.

The only thing I would really want to change programmatically is the min and max symbol size (the cylinders). Is there a way to adjust those properties?

I tested this with all the basemap options and there are many this will not work with. Here are the results with their error messages:

"streets" - works great

"satellite" - [esri.views.SceneView] #pixelSizeAt() Scene view cannot be used before it is ready

"hybrid" - works great

"topo" - works great

"gray" - works great

"dark-gray" - [esri.views.SceneView] #pixelSizeAt() Scene view cannot be used before it is ready

"oceans" - [esri.views.SceneView] #pixelSizeAt() Scene view cannot be used before it is ready

"national-geographic" - works great

"terrain" - [esri.views.SceneView] #pixelSizeAt() Scene view cannot be used before it is ready

"osm" - [esri.views.SceneView] #pixelSizeAt() Scene view cannot be used before it is ready

"dark-gray-vector" - [esri.views.SceneView] #pixelSizeAt() Scene view cannot be used before it is ready

"gray-vector" - init.js:308 [esri.views.SceneView] #pixelSizeAt() Scene view cannot be used before it is ready

"streets-vector" - [esri.views.SceneView] #pixelSizeAt() Scene view cannot be used before it is ready

"topo-vector" - [esri.views.SceneView] #pixelSizeAt() Scene view cannot be used before it is ready

"streets-night-vector" - d {name: "size-visual-variable:insufficient-info", message: "Unable to find size scheme", details: undefined}

"streets-relief-vector" - d {name: "size-visual-variable:insufficient-info", message: "Unable to find size scheme", details: undefined}

"streets-navigation-vector" - d {name: "size-visual-variable:insufficient-info", message: "Unable to find size scheme", details: undefined}

Thank you,

David

0 Kudos
KristianEkenes
Esri Regular Contributor

The only thing I would really want to change programmatically is the min and max symbol size (the cylinders). Is there a way to adjust those properties?

The currently implementation uses the view to determine the min and max size so it varies depending on the scale of the view when the method is called. We're working on improving this so it is more consistent for 3D object symbols despite the scale.

However, if you want to change the min and max sizes, you can do that manually without the smart mapping modules, using the size visual variable. The smart mapping modules don't have to be used to work with the slider widgets though they are convenient for getting the stats and histogram. Here's an example of how to override the sizes after getting back the default renderer: JS Bin - Collaborative JavaScript Debugging 

Remember, these creator functions are all about giving you a good default, or starting point. You can visualize your data anyway you want to! But these modules help give you context if you're unfamiliar with your data or you want to allow others to explore it freely.

I'll take a look at the basemap issues. Note that note all vector tile basemaps will work. Only ones that have an equivalent raster basemap will generate a renderer. The reason for this is because the styles for smart mapping were designed before vector tiles came into the API. This is an issue we're aware of and looking to fix. In the meantime you can use the basemap string id of the basemap that most closely resembles whatever you are using that may be unsupported.

0 Kudos
DavidChrest
Occasional Contributor II

Kristian,

Thanks so much for all this wonderful feedback and for that JS Bin link showing me how to override the sizes. Very helpful. Yes, I figured the view scale automatically determined the symbol size, just wanted to tweak it a bit. Looking forward to your blog article when it comes out.

David

0 Kudos