Generate a dot density visualization

Explore in the sandboxView live

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>

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 = [];
const fields = {
  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({
    numColors: fields.length,
    name: schemesList.value

dotDensityRendererCreator.createRenderer(params).then(function (response) {
  layer.renderer = response.renderer;

The esri/smartMapping/popup/templates module allows you to generate default popup templates that only contain information relevant to the layer's renderer.

function createPopupTemplate(layer){
    layer: layer
    // 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 rendererTraditional default
popup-sm-default popup-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 Visualization overview: Smart mapping API 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.

Additional visualization samples and resources