{"id":484052,"date":"2019-04-09T08:00:07","date_gmt":"2019-04-09T15:00:07","guid":{"rendered":"http:\/\/www.esri.com\/arcgis-blog\/?post_type=blog&#038;p=484052"},"modified":"2019-04-09T12:00:17","modified_gmt":"2019-04-09T19:00:17","slug":"interactive-dot-density-maps-for-the-web","status":"publish","type":"blog","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web","title":{"rendered":"Interactive dot density maps for the web"},"author":6561,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","format":"standard","meta":{"_acf_changed":false,"_searchwp_excluded":""},"categories":[22941],"tags":[30111,35751,27491,368772,345572],"industry":[],"product":[36831,36601],"class_list":["post-484052","blog","type-blog","status-publish","format-standard","hentry","category-mapping","tag-data-visualization","tag-dot-density","tag-jsapi4","tag-legend","tag-whats-new-march-2019","product-js-api-arcgis","product-developers"],"acf":{"short_description":"Add an interactive legend to your dot density map for data exploration purposes.","flexible_content":[{"acf_fc_layout":"content","content":"<p>At <a href=\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/announcements\/whats-new-in-arcgis-api-for-javascript-4-11-march-2019\/\">version 4.11<\/a> of the <a href=\"https:\/\/developers.arcgis.com\/javascript\/\">ArcGIS API for JavaScript<\/a> (ArcGIS JS API), we added support for <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-renderers-DotDensityRenderer.html\">DotDensityRenderer<\/a>, which visualizes the density of a population or count in polygon layers. Last week <a href=\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/dot-density-for-the-web\/\">I wrote an introduction<\/a> to these visualizations. In this post, I\u2019ll demonstrate how to add custom behavior to the <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-widgets-Legend.html\">Legend<\/a>, to transform it into a data exploration tool allowing users to explore dot density maps in more depth.<\/p>\n<p>In <a href=\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/dot-density-for-the-web\/\">Dot density maps for the web<\/a>, I demonstrated how to create <a href=\"https:\/\/ekenes.github.io\/esri-js-samples\/4\/visualization\/dot-density\/population-race.html\">this app<\/a>, which visualizes population density by race\/ethnicity in the United States.<\/p>\n"},{"acf_fc_layout":"image","image":{"ID":476532,"id":476532,"title":"nyc-100-small","filename":"nyc-100-small-2.png","filesize":172647,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/nyc-100-small-2.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/dot-density-for-the-web\/nyc-100-small-3","alt":"1 dot represents 100 people at a city scale.","author":"6561","description":"","caption":"One dot represents 100 people at a city scale.","name":"nyc-100-small-3","status":"inherit","uploaded_to":475292,"date":"2019-03-29 15:51:09","modified":"2019-03-29 15:52:28","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":800,"height":483,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/nyc-100-small-2-150x150.png","thumbnail-width":150,"thumbnail-height":150,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/nyc-100-small-2.png","medium-width":432,"medium-height":261,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/nyc-100-small-2.png","medium_large-width":768,"medium_large-height":464,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/nyc-100-small-2.png","large-width":800,"large-height":483,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/nyc-100-small-2.png","1536x1536-width":800,"1536x1536-height":483,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/nyc-100-small-2.png","2048x2048-width":800,"2048x2048-height":483,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/nyc-100-small-2-770x465.png","card_image-width":770,"card_image-height":465,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/nyc-100-small-2.png","wide_image-width":800,"wide_image-height":483}},"image_position":"center","orientation":"horizontal","hyperlink":"https:\/\/ekenes.github.io\/esri-js-samples\/4\/visualization\/dot-density\/population-race.html"},{"acf_fc_layout":"content","content":"<p>While the visual is fun to explore on its own, you may want to focus on one data category at a time. This can be difficult in highly dense areas for a couple of reasons: <\/p>\n<p>1. One category could clearly dominate and occlude all others, or<br \/>\n2. Several categories could be evenly represented, making it difficult to discern which ones are present.<\/p>\n<p>Let&#8217;s take a look at various ways you can make dot density visualizations more interactive, allowing users to explore individual data categories.<\/p>\n<h3>Copy the same layer for each attribute<\/h3>\n<p>You could allow the user to explore individual categories by creating up to eight separate layers that visualize each field with a different color. You can even add a <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-widgets-LayerList.html\">LayerList<\/a> widget with an embedded Legend to toggle layer visibility:<\/p>\n<pre><code style=\"padding: 0.5em;color: #333;background: #f8f8f8\">\r\nview.ui.add( <span style=\"color: #333;font-weight: bold\">new<\/span> LayerList({ \r\n  view: view, \r\n  listItemCreatedFunction: <span><span style=\"color: #333;font-weight: bold\">function<\/span>(<span>event<\/span>) <\/span>{\r\n    <span style=\"color: #333;font-weight: bold\">const<\/span> item = event.item;\r\n    item.panel = {\r\n      content: [<span style=\"color: #d14\">\"legend\"<\/span>],\r\n      open: <span style=\"color: #333;font-weight: 500\">true<\/span>\r\n    };\r\n  }\r\n}), <span style=\"color: #d14\">\"top-left\"<\/span>);\r\n\r\n<\/code><\/pre>\n<p>This allows the user to not only view one category at a time, but any combination of categories at a single time. This can be appropriate for some purposes, but it also makes the LayerList\/Legend long, redundant, and frankly kind of awkward to use when as many as eight layers are included.<\/p>\n"},{"acf_fc_layout":"image","image":{"ID":486422,"id":486422,"title":"layerlist-large","filename":"layerlist-large.gif","filesize":207493,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/layerlist-large.gif","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web\/layerlist-large","alt":"","author":"6561","description":"","caption":"Population density by race in the United States. Each category is represented by a separate layer and can be toggled using the LayerList widget.","name":"layerlist-large","status":"inherit","uploaded_to":484052,"date":"2019-04-08 23:45:56","modified":"2019-04-08 23:46:03","menu_order":0,"mime_type":"image\/gif","type":"image","subtype":"gif","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":902,"height":492,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/layerlist-large-150x150.gif","thumbnail-width":150,"thumbnail-height":150,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/layerlist-large.gif","medium-width":464,"medium-height":253,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/layerlist-large.gif","medium_large-width":768,"medium_large-height":419,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/layerlist-large.gif","large-width":902,"large-height":492,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/layerlist-large.gif","1536x1536-width":902,"1536x1536-height":492,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/layerlist-large.gif","2048x2048-width":902,"2048x2048-height":492,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/layerlist-large-826x451.gif","card_image-width":826,"card_image-height":451,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/layerlist-large.gif","wide_image-width":902,"wide_image-height":492}},"image_position":"center","orientation":"horizontal","hyperlink":"https:\/\/ekenes.github.io\/esri-js-samples\/4\/visualization\/dot-density\/population-race-layers.html"},{"acf_fc_layout":"content","content":"<p>Another drawback of this approach is performance; the geometries of each layer (the same data) are downloaded to the browser a total of eight times! This isn&#8217;t ideal considering the geometries are all the same.<\/p>\n<h3>Display each attribute in different views<\/h3>\n<p>You could do a similar visualization, but modify it by adding each layer to a different view with the same extent&#8230; <\/p>\n"},{"acf_fc_layout":"image","image":{"ID":484312,"id":484312,"title":"Screen Shot 2019-04-05 at 3.32.27 PM","filename":"Screen-Shot-2019-04-05-at-3.32.27-PM.png","filesize":351889,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-05-at-3.32.27-PM.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web\/screen-shot-2019-04-05-at-3-32-27-pm","alt":"Population density by race. Each category is visualized in a different view.","author":"6561","description":"","caption":"Population Density by race in the United States. Each category is visualized as a separate layer in the same view.","name":"screen-shot-2019-04-05-at-3-32-27-pm","status":"inherit","uploaded_to":484052,"date":"2019-04-05 23:01:13","modified":"2019-04-05 23:02:13","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":1324,"height":818,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-05-at-3.32.27-PM-150x150.png","thumbnail-width":150,"thumbnail-height":150,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-05-at-3.32.27-PM.png","medium-width":422,"medium-height":261,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-05-at-3.32.27-PM.png","medium_large-width":768,"medium_large-height":474,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-05-at-3.32.27-PM.png","large-width":1324,"large-height":818,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-05-at-3.32.27-PM.png","1536x1536-width":1324,"1536x1536-height":818,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-05-at-3.32.27-PM.png","2048x2048-width":1324,"2048x2048-height":818,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-05-at-3.32.27-PM-753x465.png","card_image-width":753,"card_image-height":465,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-05-at-3.32.27-PM.png","wide_image-width":1324,"wide_image-height":818}},"image_position":"center","orientation":"horizontal","hyperlink":"https:\/\/ekenes.github.io\/esri-js-samples\/4\/visualization\/dot-density\/population-race-views.html"},{"acf_fc_layout":"content","content":"<p><a href=\"https:\/\/ekenes.github.io\/esri-js-samples\/4\/visualization\/dot-density\/population-race-views.html\">This app<\/a> has similar performance issues because it draws eight separate views to render data from the same layer. However, it does allow us to see population density for each category at a single glance. <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/sample-code\/views-synchronize\/index.html\">I even synced the views<\/a> so you can navigate to any area in the United States and see the full breakdown of the data.<\/p>\n<p>This is particularly useful if you want to clearly see categories with smaller populations in high density areas. For example, the &#8220;Other race&#8221; and &#8220;Two or more races&#8221; categories in the image above would be difficult (if not impossible) to see in the original visualization. By displaying it in a different view, we can more easily see the whole picture of the data at once for this area.<\/p>\n<h2>Create an interactive legend<\/h2>\n<p>There may some use cases for the other two visualization styles, but I found it more fun (and performant) to explore all this data in the same view with a single layer. That\u2019s why I settled on adding custom interaction to the Legend for exploring each category.<\/p>\n<p>The <a href=\"https:\/\/ekenes.github.io\/conferences\/ds-2019\/plenary\/dot-density-legend\/index.html\">app below<\/a> doesn\u2019t look much different from the original app. However, as you hover over each Legend element, the visual will update to emphasize the category touched by the pointer.<\/p>\n"},{"acf_fc_layout":"image","image":{"ID":486412,"id":486412,"title":"dd-largest","filename":"dd-largest.gif","filesize":1088109,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/dd-largest.gif","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web\/dd-largest","alt":"","author":"6561","description":"","caption":"Population density in the U.S. by race. The user can explore individual categories by altering a single renderer on one layer instance.","name":"dd-largest","status":"inherit","uploaded_to":484052,"date":"2019-04-08 23:42:22","modified":"2019-04-08 23:42:40","menu_order":0,"mime_type":"image\/gif","type":"image","subtype":"gif","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":902,"height":492,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/dd-largest-150x150.gif","thumbnail-width":150,"thumbnail-height":150,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/dd-largest.gif","medium-width":464,"medium-height":253,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/dd-largest.gif","medium_large-width":768,"medium_large-height":419,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/dd-largest.gif","large-width":902,"large-height":492,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/dd-largest.gif","1536x1536-width":902,"1536x1536-height":492,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/dd-largest.gif","2048x2048-width":902,"2048x2048-height":492,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/dd-largest-826x451.gif","card_image-width":826,"card_image-height":451,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/dd-largest.gif","wide_image-width":902,"wide_image-height":492}},"image_position":"center","orientation":"horizontal","hyperlink":"https:\/\/ekenes.github.io\/conferences\/ds-2019\/plenary\/dot-density-legend\/index.html"},{"acf_fc_layout":"content","content":"<p>If you click one of the elements, you can freeze the emphasis on that category to resume normal interaction with the view.<\/p>\n"},{"acf_fc_layout":"image","image":{"ID":486382,"id":486382,"title":"Freeze and explore one category at a time.","filename":"Screen-Shot-2019-04-08-at-4.29.19-PM.png","filesize":230977,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-4.29.19-PM.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web\/screen-shot-2019-04-08-at-4-29-19-pm","alt":"","author":"6561","description":"","caption":"Explore one category at a time by clicking the legend element representing that category.","name":"screen-shot-2019-04-08-at-4-29-19-pm","status":"inherit","uploaded_to":484052,"date":"2019-04-08 23:37:35","modified":"2019-04-08 23:38:01","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":965,"height":557,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-4.29.19-PM-150x150.png","thumbnail-width":150,"thumbnail-height":150,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-4.29.19-PM.png","medium-width":452,"medium-height":261,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-4.29.19-PM.png","medium_large-width":768,"medium_large-height":443,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-4.29.19-PM.png","large-width":965,"large-height":557,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-4.29.19-PM.png","1536x1536-width":965,"1536x1536-height":557,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-4.29.19-PM.png","2048x2048-width":965,"2048x2048-height":557,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-4.29.19-PM-806x465.png","card_image-width":806,"card_image-height":465,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-4.29.19-PM.png","wide_image-width":965,"wide_image-height":557}},"image_position":"center","orientation":"horizontal","hyperlink":"https:\/\/ekenes.github.io\/conferences\/ds-2019\/plenary\/dot-density-legend\/index.html"},{"acf_fc_layout":"content","content":"<p>Notice the dots pertaining to non-selected categories are still present, but deemphasized &#8211; they\u2019re just given an opacity value of <code>0.2<\/code>. This allows you to get a better view of the selected category (even the small population ones) in the context of all others all while rendering a single layer of data to maximize performance.<\/p>\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=EtatruR-NBY&amp;list=PLaPDDLTCmy4Y3e8AkFYr9n-njdf2fAbS4&amp;index=9&amp;t=3m25s\">Click here to view my demo of this app at the 2019 Dev Summit plenary session<\/a>.<\/p>\n<h2>How it works<\/h2>\n<p>To add interaction to the Legend, you need to hook up the desired event listeners on the <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-widgets-Legend.html#container\">Legend container<\/a>. The Legend uses dot density attribute labels in the <code>alt<\/code> text of the DOM element representing the dot color and the <code>innerText<\/code> of the element containing the label text. <\/p>\n<p>If the pointer hits an element containing <code>alt<\/code> text or <code>innerText<\/code> in the Legend, I store that string in a variable called <code>selectedText<\/code>.<\/p>\n<p>The Legend has a <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-widgets-Legend.html#activeLayerInfos\">activeLayerInfos<\/a> property that contains information about how the Legend is rendered for each layer. For every interaction with the Legend, I check the <code>selectedText<\/code> against the <code>activeLayerInfos<\/code> labels. If the selected text matches any of the <code>activeLayerInfos<\/code>, then I call the <code>showSelectedField<\/code> function.<\/p>\n<pre><code style=\"padding: 0.5em;color: #333;background: #f8f8f8\">\r\nlegendContainer.addEventListener(<span style=\"color: #d14\">\"mousemove\"<\/span>, legendEventListener);\r\nlegendContainer.addEventListener(<span style=\"color: #d14\">\"click\"<\/span>, legendEventListener);\r\n\r\n<span style=\"color: #333;font-weight: bold\">let<\/span> mousemoveEnabled = <span style=\"color: #333;font-weight: 500\">true<\/span>;\r\n<span><span style=\"color: #333;font-weight: bold\">function<\/span> <span style=\"color: #900;font-weight: bold\">legendEventListener<\/span> (<span>event:any<\/span>) <\/span>{\r\n  <span style=\"color: #333;font-weight: bold\">const<\/span> selectedText = event.target.alt || event.target.innerText;\r\n  <span style=\"color: #333;font-weight: bold\">const<\/span> legendInfos: <span style=\"color: #0086b3\">Array<\/span>&lt;any&gt; = legend.activeLayerInfos.getItemAt(<span style=\"color: #008080\">0<\/span>).legendElements[<span style=\"color: #008080\">0<\/span>].infos;\r\n  <span style=\"color: #998;font-style: italic\">\/\/ if selectedText matches any text in the legend infos, then update the renderer<\/span>\r\n  <span style=\"color: #333;font-weight: bold\">const<\/span> matchFound = legendInfos.filter( (info:any) =&gt; info.label === selectedText ).length &gt; <span style=\"color: #008080\">0<\/span>;\r\n  \r\n  <span style=\"color: #333;font-weight: bold\">if<\/span> (matchFound){\r\n    showSelectedField(selectedText);\r\n    \r\n    <span style=\"color: #998;font-style: italic\">\/\/ additional logic for freezing view if mousemove <\/span>\r\n    <span style=\"color: #998;font-style: italic\">\/\/ was disabled would be included here<\/span>\r\n  } <span style=\"color: #333;font-weight: bold\">else<\/span> {\r\n    layer.renderer = dotDensityRenderer;\r\n  }\r\n}\r\n\r\n<\/code><\/pre>\n<p>This function modifies the renderer so all categories whose labels don\u2019t match the selected label are assigned the same color, but with an opacity value of 0.2.<\/p>\n<pre><code style=\"padding: 0.5em;color: #333;background: #f8f8f8\">\r\n<span><span style=\"color: #333;font-weight: bold\">function<\/span> <span style=\"color: #900;font-weight: bold\">showSelectedField<\/span> (<span>label: string<\/span>) <\/span>{\r\n  <span style=\"color: #333;font-weight: bold\">const<\/span> oldRenderer = layer.renderer <span style=\"color: #333;font-weight: bold\">as<\/span> DotDensityRenderer;\r\n  <span style=\"color: #333;font-weight: bold\">const<\/span> newRenderer = oldRenderer.clone();\r\n  <span style=\"color: #333;font-weight: bold\">const<\/span> attributes = newRenderer.attributes.map( attribute =&gt; {\r\n    attribute.color.a = attribute.label === label ? <span style=\"color: #008080\">1<\/span> : <span style=\"color: #008080\">0.2<\/span>;\r\n    <span style=\"color: #333;font-weight: bold\">return<\/span> attribute;\r\n  });\r\n  newRenderer.attributes = attributes;\r\n  layer.renderer = newRenderer;\r\n}\r\n\r\n<\/code><\/pre>\n<p>If the selection doesn\u2019t include any text or text that doesn\u2019t match any label from the renderer\u2019s attributes, then I set the original renderer back on the layer. <\/p>\n<p>As you can see, with just a little bit of customization, you can create highly interactive dot density visualizations for data exploration purposes. This is just one way you can do that. Stay tuned for more posts exploring dot density in the ArcGIS JS API.<\/p>\n"}],"authors":[{"ID":6561,"user_firstname":"Kristian","user_lastname":"Ekenes","nickname":"Kristian Ekenes","user_nicename":"kekenes","display_name":"Kristian Ekenes","user_email":"KEkenes@esri.com","user_url":"https:\/\/github.com\/ekenes","user_registered":"2018-03-02 00:18:32","user_description":"Kristian Ekenes is a Principal Product Engineer at Esri specializing in data visualization on the web. He works on the ArcGIS Maps SDK for JavaScript, ArcGIS Arcade, and Map Viewer in ArcGIS Online. Kristian's work focuses on researching and developing new and innovative data visualization capabilities of geospatial data in web maps, Arcade integration in web maps, and applications of generative AI assistants in web maps. Prior to joining Esri, he worked as a GIS Specialist for an environmental consulting company. Kristian has degrees from Brigham Young University and Arizona State University.","user_avatar":"<img data-del=\"avatar\" src='https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2021\/10\/ekenes-zurich-213x200.png' class='avatar pp-user-avatar avatar-96 photo ' height='96' width='96'\/>"}],"related_articles":[{"ID":475292,"post_author":"6561","post_date":"2019-04-01 08:00:33","post_date_gmt":"2019-04-01 15:00:33","post_content":"","post_title":"Dot density for the web","post_excerpt":"","post_status":"publish","comment_status":"closed","ping_status":"closed","post_password":"","post_name":"dot-density-for-the-web","to_ping":"","pinged":"","post_modified":"2019-04-09 11:59:44","post_modified_gmt":"2019-04-09 18:59:44","post_content_filtered":"","post_parent":0,"guid":"http:\/\/www.esri.com\/arcgis-blog\/?post_type=blog&#038;p=475292","menu_order":0,"post_type":"blog","post_mime_type":"","comment_count":"0","filter":"raw"}],"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/card-final.png","wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/banner-3.jpg"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.9 (Yoast SEO v25.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Interactive dot density maps for the web<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Interactive dot density maps for the web\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web\" \/>\n<meta property=\"og:site_name\" content=\"ArcGIS Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/esrigis\/\" \/>\n<meta property=\"article:modified_time\" content=\"2019-04-09T19:00:17+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@ESRI\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web\"},\"author\":{\"name\":\"Kristian Ekenes\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/5469f723fbfb78138efbb1da56e6aa9b\"},\"headline\":\"Interactive dot density maps for the web\",\"datePublished\":\"2019-04-09T15:00:07+00:00\",\"dateModified\":\"2019-04-09T19:00:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web\"},\"wordCount\":7,\"publisher\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\"},\"keywords\":[\"data visualization\",\"dot density\",\"jsapi4\",\"legend\",\"whats new march 2019\"],\"articleSection\":[\"Mapping\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web\",\"name\":\"Interactive dot density maps for the web\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#website\"},\"datePublished\":\"2019-04-09T15:00:07+00:00\",\"dateModified\":\"2019-04-09T19:00:17+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.esri.com\/arcgis-blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Interactive dot density maps for the web\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#website\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/\",\"name\":\"ArcGIS Blog\",\"description\":\"Get insider info from Esri product teams\",\"publisher\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.esri.com\/arcgis-blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\",\"name\":\"Esri\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png\",\"contentUrl\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png\",\"width\":400,\"height\":400,\"caption\":\"Esri\"},\"image\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/esrigis\/\",\"https:\/\/x.com\/ESRI\",\"https:\/\/www.linkedin.com\/company\/5311\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/5469f723fbfb78138efbb1da56e6aa9b\",\"name\":\"Kristian Ekenes\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2021\/10\/ekenes-zurich-213x200.png\",\"contentUrl\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2021\/10\/ekenes-zurich-213x200.png\",\"caption\":\"Kristian Ekenes\"},\"description\":\"Kristian Ekenes is a Principal Product Engineer at Esri specializing in data visualization on the web. He works on the ArcGIS Maps SDK for JavaScript, ArcGIS Arcade, and Map Viewer in ArcGIS Online. Kristian's work focuses on researching and developing new and innovative data visualization capabilities of geospatial data in web maps, Arcade integration in web maps, and applications of generative AI assistants in web maps. Prior to joining Esri, he worked as a GIS Specialist for an environmental consulting company. Kristian has degrees from Brigham Young University and Arizona State University.\",\"sameAs\":[\"https:\/\/github.com\/ekenes\",\"https:\/\/www.linkedin.com\/in\/kristian-ekenes\/\",\"https:\/\/x.com\/kekenes\"],\"gender\":\"male\",\"jobTitle\":\"Principal Product Engineer\",\"worksFor\":\"Esri\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/author\/kekenes\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Interactive dot density maps for the web","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web","og_locale":"en_US","og_type":"article","og_title":"Interactive dot density maps for the web","og_url":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web","og_site_name":"ArcGIS Blog","article_publisher":"https:\/\/www.facebook.com\/esrigis\/","article_modified_time":"2019-04-09T19:00:17+00:00","twitter_card":"summary_large_image","twitter_site":"@ESRI","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web#article","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web"},"author":{"name":"Kristian Ekenes","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/5469f723fbfb78138efbb1da56e6aa9b"},"headline":"Interactive dot density maps for the web","datePublished":"2019-04-09T15:00:07+00:00","dateModified":"2019-04-09T19:00:17+00:00","mainEntityOfPage":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web"},"wordCount":7,"publisher":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization"},"keywords":["data visualization","dot density","jsapi4","legend","whats new march 2019"],"articleSection":["Mapping"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web","url":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web","name":"Interactive dot density maps for the web","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#website"},"datePublished":"2019-04-09T15:00:07+00:00","dateModified":"2019-04-09T19:00:17+00:00","breadcrumb":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/mapping\/interactive-dot-density-maps-for-the-web#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.esri.com\/arcgis-blog\/"},{"@type":"ListItem","position":2,"name":"Interactive dot density maps for the web"}]},{"@type":"WebSite","@id":"https:\/\/www.esri.com\/arcgis-blog\/#website","url":"https:\/\/www.esri.com\/arcgis-blog\/","name":"ArcGIS Blog","description":"Get insider info from Esri product teams","publisher":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.esri.com\/arcgis-blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization","name":"Esri","url":"https:\/\/www.esri.com\/arcgis-blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png","contentUrl":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png","width":400,"height":400,"caption":"Esri"},"image":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/esrigis\/","https:\/\/x.com\/ESRI","https:\/\/www.linkedin.com\/company\/5311\/"]},{"@type":"Person","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/5469f723fbfb78138efbb1da56e6aa9b","name":"Kristian Ekenes","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/image\/","url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2021\/10\/ekenes-zurich-213x200.png","contentUrl":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2021\/10\/ekenes-zurich-213x200.png","caption":"Kristian Ekenes"},"description":"Kristian Ekenes is a Principal Product Engineer at Esri specializing in data visualization on the web. He works on the ArcGIS Maps SDK for JavaScript, ArcGIS Arcade, and Map Viewer in ArcGIS Online. Kristian's work focuses on researching and developing new and innovative data visualization capabilities of geospatial data in web maps, Arcade integration in web maps, and applications of generative AI assistants in web maps. Prior to joining Esri, he worked as a GIS Specialist for an environmental consulting company. Kristian has degrees from Brigham Young University and Arizona State University.","sameAs":["https:\/\/github.com\/ekenes","https:\/\/www.linkedin.com\/in\/kristian-ekenes\/","https:\/\/x.com\/kekenes"],"gender":"male","jobTitle":"Principal Product Engineer","worksFor":"Esri","url":"https:\/\/www.esri.com\/arcgis-blog\/author\/kekenes"}]}},"text_date":"April 9, 2019","author_name":"Kristian Ekenes","author_page":"https:\/\/www.esri.com\/arcgis-blog\/author\/kekenes","custom_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2019\/03\/banner-3.jpg","primary_product":"ArcGIS Maps SDK for JavaScript","tag_data":[{"term_id":30111,"name":"data visualization","slug":"data-visualization","term_group":0,"term_taxonomy_id":30111,"taxonomy":"post_tag","description":"","parent":0,"count":97,"filter":"raw"},{"term_id":35751,"name":"dot density","slug":"dot-density","term_group":0,"term_taxonomy_id":35751,"taxonomy":"post_tag","description":"","parent":0,"count":8,"filter":"raw"},{"term_id":27491,"name":"jsapi4","slug":"jsapi4","term_group":0,"term_taxonomy_id":27491,"taxonomy":"post_tag","description":"","parent":0,"count":111,"filter":"raw"},{"term_id":368772,"name":"legend","slug":"legend","term_group":0,"term_taxonomy_id":368772,"taxonomy":"post_tag","description":"","parent":0,"count":5,"filter":"raw"},{"term_id":345572,"name":"whats new march 2019","slug":"whats-new-march-2019","term_group":0,"term_taxonomy_id":345572,"taxonomy":"post_tag","description":"","parent":0,"count":20,"filter":"raw"}],"category_data":[{"term_id":22941,"name":"Mapping","slug":"mapping","term_group":0,"term_taxonomy_id":22941,"taxonomy":"category","description":"","parent":0,"count":2683,"filter":"raw"}],"product_data":[{"term_id":36831,"name":"ArcGIS Maps SDK for JavaScript","slug":"js-api-arcgis","term_group":0,"term_taxonomy_id":36831,"taxonomy":"product","description":"","parent":36601,"count":361,"filter":"raw"},{"term_id":36601,"name":"Developers","slug":"developers","term_group":0,"term_taxonomy_id":36601,"taxonomy":"product","description":"","parent":0,"count":761,"filter":"raw"}],"primary_product_link":"https:\/\/www.esri.com\/arcgis-blog\/?s=#&products=js-api-arcgis","_links":{"self":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/484052","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/users\/6561"}],"replies":[{"embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/comments?post=484052"}],"version-history":[{"count":0,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/484052\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/media?parent=484052"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/categories?post=484052"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/tags?post=484052"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/industry?post=484052"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/product?post=484052"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}