This sample demonstrates how to generate a dot density visualization based on a set of complementary numeric fields in a FeatureLayer. This is accomplished with the createRenderer() method in the dot density renderer creator helper object.
Dot density visualizations are exclusively used for visualizing density values in polygon layers. The density is visualized by randomly placing one dot per a given value for the desired attribute. Unlike choropleth visualizations, dot density can be mapped using total counts since the size of the polygon plays a significant role in the perceived density of the attribute.
While dot density is most commonly mapped with a single attribute, you may specify up to 8 fields and/or Arcade expressions to view subsets of the data. These fields should be subsets of a common category, or in competition with one another.
This sample visualizes the number of homes in Census block groups in the United States based on the 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 complementary fields because a housing unit cannot finish construction in more than one decade. To illustrate how this method works, we expose all the competing fields to the user in a select
element.
<select id="fieldList" multiple="multiple" size="8" 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="$feature.ACSBLT2000 + $feature.ACSBLT2010 + $feature.ACSBLT2014" selected>After 2000</option>
</select>
Then add a function that generates the dot density renderer each time the user adds or removes a field from the visualization.
function isArcade(stringValue){
return stringValue.indexOf("$feature") !== -1;
}
const selectedOptions = [].slice.call(fieldList.selectedOptions);
const fields = selectedOptions.map((option) => {
return {
field: isArcade(option.value) ? null : option.value,
valueExpression: isArcade(option.value) ? option.value : null,
label: option.text
};
});
const params = {
view: view,
layer: layer,
attributes: fields,
legendOptions: {
unit: "homes"
},
// Uses the scheme selected by the user
dotDensityScheme: dotDensitySymbology.getSchemeByName({
basemap: view.map.basemap,
numColors: fields.length,
name: schemesList.value
})
};
dotDensityRendererCreator.createRenderer(params).then((response) => {
layer.renderer = response.renderer;
});
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.