This sample demonstrates how to generate a predominance visualization based on a set of competing numeric fields in a FeatureLayer. This is accomplished with the createRenderer() method in the predominance renderer creator helper object.
Visualizing predominance involves coloring a layer’s features based on which attribute among a set of competing numeric attributes wins or beats the others in total count. Common applications of this include visualizing election results, survey results, and demographic majorities.
This sample visualizes block groups in Boise, Idaho based on the predominant decade in which homes were constructed. If you glance at the service metadata for the layer, you'll see a list of ten numeric fields containing a count of housing units based on the decade they were constructed.
These are competing fields because a housing unit cannot finish construction in more than one decade.
To illustrate how predominance works, we expose all the competing fields to the user in a select
element.
<select id="fieldList" multiple="multiple" size="10" class="esri-widget">
<option value="ACSBLT1939" selected>Before 1940</option>
<option value="ACSBLT1940" selected>1940-1949</option>
<option value="ACSBLT1950" selected>1950-1959</option>
<option value="ACSBLT1960" selected>1960-1969</option>
<option value="ACSBLT1970" selected>1970-1979</option>
<option value="ACSBLT1980" selected>1980-1989</option>
<option value="ACSBLT1990" selected>1990-1999</option>
<option value="ACSBLT2000" selected>2000-2009</option>
<option value="ACSBLT2010" selected>2010-2013</option>
<option value="ACSBLT2014" selected>After 2013</option>
</select>
Then add a function that generates the predominance renderer each time the user adds or removes a field from the visualization.
const selectedOptions = [].slice.call(fieldList.selectedOptions);
const fields = selectedOptions.map((option) => {
return {
name: option.value, // field name from the select element
label: option.text // label from the select element
};
});
const params = {
view: view,
layer: layer,
fields: fields,
includeSizeVariable: includeSizeCheckbox.checked,
includeOpacityVariable: includeOpacityCheckbox.checked,
legendOptions: {
title: "Most common decade in which homes were built"
}
};
return predominanceRendererCreator.createRenderer(params)
.then((response) => {
layer.renderer = response.renderer;
});
You can optionally include a size and/or an opacity visual variable to add another dimension to the visualization. When the opacity variable is enabled, high opacity features indicate highly predominant values. Features where the predominant value beats others by a small margin will be assigned a low opacity, indicating that while the feature has a winning value, it doesn't win by much.
When the size variable is enabled, features will be assigned a size based on the sum of all competing values. Features with small total counts will be sized with small icons or lines depending on the geometry type of the layer, and features with large total counts will be sized with large icons or lines. Enabling this option is good for visualizing how influential a particular feature is compared to the dataset as a whole. It removes bias introduced by features with large geographic areas, but relatively small data values.
The esri/smart
module allows you to generate default popup templates that only contain information relevant to the layer's renderer.
function createPopupTemplate(layer){
popupTemplateCreator.getTemplates({
layer: layer
}).then((response) => {
// the response may also contain secondary
// templates you can choose from
layer.popupTemplate = response.primaryTemplate.value;
})
}
This provides a better default popup template than the traditional approach of providing a long table of unformatted values.
Suggested default template based on renderer | Traditional default |
---|---|
A word of caution
Keep in mind that generating renderers should be avoided in most applications because of the performance cost affecting the end user. As stated in the Smart Mapping guide topic, the Smart Mapping APIs were designed for two types of applications: data exploration apps and visualization authoring apps similar to ArcGIS Online. In all other cases, renderers should be saved to the layer or manually created using any of the renderer classes.