{"id":72001,"date":"2016-05-25T06:00:32","date_gmt":"2016-05-25T06:00:32","guid":{"rendered":"http:\/\/www.esri.com\/arcgis-blog\/products\/product\/uncategorized\/smart-mapping-with-dynamic-workspaces\/"},"modified":"2018-05-25T22:42:20","modified_gmt":"2018-05-25T22:42:20","slug":"smart-mapping-with-dynamic-workspaces","status":"publish","type":"blog","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces","title":{"rendered":"Smart Mapping with dynamic workspaces"},"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":[23201,30791,30801,24921,29541,24581,29401,30811],"industry":[],"product":[36831,36601],"class_list":["post-72001","blog","type-blog","status-publish","format-standard","hentry","category-mapping","tag-cartographic-design","tag-color","tag-dynamic-layers","tag-javascript","tag-rendering","tag-smart-mapping","tag-web","tag-workspace","product-js-api-arcgis","product-developers"],"acf":{"short_description":"Not too long ago I wrote a post about how and why you may want to use Smart Mapping in custom web apps using the ArcGIS API for JavaScrip...","flexible_content":[{"acf_fc_layout":"content","content":"<p>Not too long ago <a href=\"https:\/\/blogs.esri.com\/esri\/arcgis\/2016\/03\/28\/using-smart-mapping-in-custom-web-apps\/\">I wrote a post<\/a> about how and why you may want to use <a href=\"https:\/\/blogs.esri.com\/esri\/arcgis\/2015\/03\/02\/introducing-smart-mapping\/\">Smart Mapping<\/a> in custom web apps using the <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/\">ArcGIS API for JavaScript<\/a>. The <a href=\"https:\/\/ekenes.github.io\/esri-js-samples\/smart-mapping\/seattle-demographics.html\">sample<\/a> featured in that post showed how to dynamically change the symbology of a FeatureLayer with the SmartMapping module and its accompanying slider widgets.<\/p>\n<p>Since the release of <a href=\"http:\/\/www.esri.com\/software\/arcgis\/smart-mapping\">Smart Mapping<\/a>, some users have asked about how to use the <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/esri.renderers.smartmapping-amd.html\">SmartMapping module<\/a> to change the default rendering of <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/arcgisdynamicmapservicelayer-amd.html\">dynamic layers<\/a> based on attributes from joined tables in dynamic workspaces. The following sample demonstrates how to accomplish this.<\/p>\n<p><a href=\"https:\/\/ekenes.github.io\/esri-js-samples\/smart-mapping\/dynamic-layer-join.html\"><strong>View the live sample<\/strong><\/a><br \/>\n<a href=\"https:\/\/ekenes.github.io\/esri-js-samples\/smart-mapping\/dynamic-layer-join.html\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2016\/05\/sm-dynamic-workspace.png\" alt=\"\" width=\"930\" height=\"668\" class=\"alignnone size-full wp-image-63495\" \/><\/a><br \/>\n<a href=\"https:\/\/github.com\/ekenes\/esri-js-samples\/blob\/master\/smart-mapping\/dynamic-layer-join.html\"><strong>View the code on GitHub<\/strong><\/a><\/p>\n<p>This workflow is useful in cases where you have several tables with dozens, even hundreds of attributes useful for visualization. Creating a <a href=\"https:\/\/server.arcgis.com\/en\/server\/latest\/publish-services\/linux\/what-is-a-feature-service-.htm\">feature service<\/a> or publishing all of the tables to a <a href=\"https:\/\/server.arcgis.com\/en\/server\/latest\/publish-services\/windows\/what-is-a-map-service.htm\">dynamic map service<\/a> can be impractical because of the long amount of time it can take to load large services in web apps. Instead, you can create a map service containing only geometries and minimal attributes and enable dynamic workspaces via your ArcGIS Server Manager. This will allow you to register databases and directories to a <a href=\"http:\/\/server.arcgis.com\/en\/server\/latest\/publish-services\/windows\/about-dynamic-layers.htm\">dynamic workspace<\/a>, providing your service access to resources in joined tables at runtime. This keeps the service lean, but provides it access to potentially hundreds of attributes that may be used for visualization purposes.<\/p>\n<h2>Sample overview<\/h2>\n<p>In <a href=\"https:\/\/ekenes.github.io\/esri-js-samples\/smart-mapping\/dynamic-layer-join.html\">the sample above<\/a> we add an <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/arcgisdynamicmapservicelayer-amd.html\">ArcGISDynamicMapServiceLayer<\/a> instance to the map. The layer contains several sublayers &#8211; each containing features with geometries at different resolutions: block groups, counties, and states. The service contains a fair number of attributes, including population statistics based on age, gender, marital status, etc.<\/p>\n<p>We can change the renderer of each layer based on any of these attributes, but we want to explore another set of attributes containing ancestry statistics that don&#8217;t exist in the layer itself. The ancestry attributes reside in a joined table referenced in a dynamic workspace set by the service administrator. We want the user to select a country in a dropdown menu which then makes a call to the SmartMapping module to change the symbology for each state based on the percentage of people that can trace their ancestry to the selected country.<\/p>\n<p>Before getting into some of the details of this sample, keep in mind that generating renderers with the SmartMapping module is only supported for <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/featurelayer-amd.html\">FeatureLayer<\/a>. You may apply renderers generated with SmartMapping to dynamic layers, but this requires additional network requests to calculate statistics necessary to create a renderer that fits your data. So this workflow can get a little complicated and still carry a performance cost.<\/p>\n<h2>Create a dynamic layer with a joined table<\/h2>\n<p>First we need to create a dynamic layer with a joined data source. To accomplish this, we must create a <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/joindatasource-amd.html\">JoinDataSource<\/a> object, which contains information for the left and right tables and their respective keys to perform the join.<\/p>\n<pre><span style=\"color: #333;font-weight: bold\">var<\/span> joinDataSource = <span style=\"color: #333;font-weight: bold\">new<\/span> JoinDataSource({\r\n  joinType: <span style=\"color: #d14\">\"left-outer-join\"<\/span>,\r\n  <span style=\"color: #998;font-style: italic\">\/\/<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/ Sets the left table source (layer with geometries) to the joinDataSource<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/ object. All we need to specify is the sublayer id of the map layer.<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/<\/span>\r\n  leftTableSource: <span style=\"color: #333;font-weight: bold\">new<\/span> LayerMapSource({\r\n    type: <span style=\"color: #d14\">\"mapLayer\"<\/span>,\r\n    mapLayerId: <span style=\"color: #008080\">3<\/span> <span style=\"color: #998;font-style: italic\">\/\/ The index of the states sublayer<\/span>\r\n  }),\r\n  <span style=\"color: #998;font-style: italic\">\/\/ the field in the map service indicating the state name<\/span>\r\n  leftTableKey: <span style=\"color: #d14\">\"STATE_NAME\"<\/span>,\r\n  <span style=\"color: #998;font-style: italic\">\/\/ the field in the joining table indicating the state name<\/span>\r\n  rightTableKey: <span style=\"color: #d14\">\"State\"<\/span>,\r\n  <span style=\"color: #998;font-style: italic\">\/\/<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/ Sets the right table source (the attribute table to join) to<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/ the states layer in the map service. This object will be used to complete<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/ the join to the dynamic service (the layer with the geometries).<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/<\/span>\r\n  rightTableSource: <span style=\"color: #333;font-weight: bold\">new<\/span> LayerDataSource({\r\n    dataSource: <span style=\"color: #333;font-weight: bold\">new<\/span> TableDataSource({\r\n      type: <span style=\"color: #d14\">\"table\"<\/span>,  <span style=\"color: #998;font-style: italic\">\/\/ indicates the data source is a table<\/span>\r\n      <span style=\"color: #998;font-style: italic\">\/\/ workspace where the table resides (defined in ArcGIS Server Manager)<\/span>\r\n      workspaceId: <span style=\"color: #d14\">\"CensusFileGDBWorkspaceID\"<\/span>,  \r\n      dataSourceName: <span style=\"color: #d14\">\"ancestry\"<\/span>  <span style=\"color: #998;font-style: italic\">\/\/ the table name<\/span>\r\n    })\r\n  })\r\n});\r\n<\/pre>\n<p><a href=\"https:\/\/github.com\/ekenes\/esri-js-samples\/blob\/master\/smart-mapping\/dynamic-layer-join.html#L123-L166\"><strong>View the code on GitHub<\/strong><\/a><\/p>\n<p>Then we add the JoinDataSource as a source to a <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/dynamiclayerinfo-amd.html\">DynamicLayerInfo<\/a> object, which is then set on the <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/arcgisdynamicmapservicelayer-amd.html\">ArcGISDynamicMapServiceLayer<\/a>. This completes the process of the join. Now all attributes in the ancestry table are available to the census layer.<\/p>\n<pre><span style=\"color: #998;font-style: italic\">\/\/<\/span>\r\n<span style=\"color: #998;font-style: italic\">\/\/ Create the dynamic layer data source for a DynamicLayerInfo instance.<\/span>\r\n<span style=\"color: #998;font-style: italic\">\/\/ This is a join data source and completes the join between the table<\/span>\r\n<span style=\"color: #998;font-style: italic\">\/\/ full of attributes and the layer containing geometries.<\/span>\r\n<span style=\"color: #998;font-style: italic\">\/\/<\/span>\r\n\r\n<span style=\"color: #333;font-weight: bold\">var<\/span> dynamicLayerDataSource = <span style=\"color: #333;font-weight: bold\">new<\/span> LayerDataSource({\r\n  dataSource: joinDataSource  <span style=\"color: #998;font-style: italic\">\/\/ this data source was created in the previous step<\/span>\r\n});\r\n\r\n<span style=\"color: #998;font-style: italic\">\/\/ Creates an array of dynamicLayerInfo objects for all sublayers in the service<\/span>\r\n<span style=\"color: #333;font-weight: bold\">var<\/span> dynamicLayerInfosArray = censusMapServiceLayer.createDynamicLayerInfosFromLayerInfos();\r\n\r\n<span style=\"color: #998;font-style: italic\">\/\/ Find the dynamicLayerInfo object for the states sublayer<\/span>\r\n<span style=\"color: #333;font-weight: bold\">var<\/span> dynamicLayerInfo = dynamicLayerInfosArray.find(<span style=\"color: #333;font-weight: bold\">function<\/span>(dynamicLayerInfoItem){\r\n  <span style=\"color: #333;font-weight: bold\">return<\/span> dynamicLayerInfoItem.name === <span style=\"color: #d14\">\"states\"<\/span>;\r\n});\r\n\r\n<span style=\"color: #998;font-style: italic\">\/\/ set the dynamic layer info object on the census map service layer<\/span>\r\ndynamicLayerInfo.source = dynamicLayerDataSource;\r\ncensusMapServiceLayer.setDynamicLayerInfos([dynamicLayerInfo], <span style=\"color: #333;font-weight: 500\">true<\/span>);\r\n<\/pre>\n<p><a href=\"https:\/\/github.com\/ekenes\/esri-js-samples\/blob\/master\/smart-mapping\/dynamic-layer-join.html#L168-L197\"><strong>View the code on GitHub<\/strong><\/a><\/p>\n<h2>Create a FeatureLayer<\/h2>\n<p><a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/esri.renderers.smartmapping-amd.html\">SmartMapping<\/a> only supports <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/featurelayer-amd.html\">FeatureLayer<\/a>. Therefore, to leverage SmartMapping capabilities in this use case, we must create a FeatureLayer instance used solely for generating a good default renderer. Note that the layer url must point to the dynamicLayer endpoint on the map service and the <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/featurelayer-amd.html#source\">source<\/a> of the layer must point to the <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/layerdatasource-amd.html\">dynamicLayerDataSource<\/a> object we created in the previous step. This ensures the FeatureLayer has access to the joined table in the dynamic workspace.<\/p>\n<pre><span style=\"color: #998;font-style: italic\">\/\/<\/span>\r\n<span style=\"color: #998;font-style: italic\">\/\/ Create a FeatureLayer with the joined data source so the SmartMapping<\/span>\r\n<span style=\"color: #998;font-style: italic\">\/\/ module can access the data in the joined table for generating a<\/span>\r\n<span style=\"color: #998;font-style: italic\">\/\/ renderer to apply to the DynamicLayer. SmartMapping can only<\/span>\r\n<span style=\"color: #998;font-style: italic\">\/\/ generate renderers based on FeatureLayer instances.<\/span>\r\n<span style=\"color: #998;font-style: italic\">\/\/<\/span>\r\n\r\n<span style=\"color: #998;font-style: italic\">\/\/ Set options for the feature layer instance<\/span>\r\n<span style=\"color: #333;font-weight: bold\">var<\/span> layerOptions = {\r\n  mode: FeatureLayer.MODE_SELECTION,\r\n  outFields: [<span style=\"color: #d14\">\"*\"<\/span>],\r\n  <span style=\"color: #998;font-style: italic\">\/\/ set the source to the JoinDataSource so the SmartMapping module<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/ can have access to the data in the fields from the joined table<\/span>\r\n  source: dynamicLayerDataSource\r\n};\r\n\r\n<span style=\"color: #998;font-style: italic\">\/\/ Create the layer with the url to the dynamic layer<\/span>\r\n<span style=\"color: #333;font-weight: bold\">var<\/span> featureLayer = <span style=\"color: #333;font-weight: bold\">new<\/span> FeatureLayer(layerUrl + <span style=\"color: #d14\">\"\/dynamicLayer\"<\/span>, layerOptions);\r\n<\/pre>\n<p><a href=\"https:\/\/github.com\/ekenes\/esri-js-samples\/blob\/master\/smart-mapping\/dynamic-layer-join.html#L249-L268\"><strong>View the code on GitHub<\/strong><\/a><\/p>\n<h2>Generate a renderer<\/h2>\n<p>Now all we need to do is use the FeatureLayer instance to generate a renderer with smart defaults based on the ancestry field selected by the user. In the snippet below, we call the <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/esri.renderers.smartmapping-amd.html#createclassedcolorrenderer\">createClassedColorRenderer()<\/a> method to generate a <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/classbreaksrenderer-amd.html\">ClassBreaksRenderer<\/a> based on color. Notice how the FeatureLayer is used as an input parameter for generating the renderer, but the renderer itself is set to the <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/arcgisdynamicmapservicelayer-amd.html#setlayerdrawingoptions\">drawingInfo<\/a> of the dynamic layer with an instance of the <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/layerdrawingoptions-amd.html\">LayerDrawingOptions<\/a> module.<\/p>\n<pre>smartMapping.createClassedColorRenderer({\r\n  <span style=\"color: #998;font-style: italic\">\/\/ selected by the user<\/span>\r\n  basemap: basemapStyle,\r\n  classificationMethod: <span style=\"color: #d14\">\"natural-breaks\"<\/span>,\r\n  <span style=\"color: #998;font-style: italic\">\/\/ ancestry table field selected by the user<\/span>\r\n  field: ancestryClassificationField,\r\n  <span style=\"color: #998;font-style: italic\">\/\/ featureLayer created in the previous step<\/span>\r\n  layer: featureLayer,\r\n  <span style=\"color: #998;font-style: italic\">\/\/ normalize by the total population<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/ note the field name is prefixed by 'states'.<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/ this indicates the workspace where the field<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/ is located - the states sublayer of the service<\/span>\r\n  normalizationField: <span style=\"color: #d14\">\"states.POP2007\"<\/span>,\r\n  normalizationType: <span style=\"color: #d14\">\"field\"<\/span>,\r\n  numClasses: <span style=\"color: #008080\">7<\/span>\r\n}).then(<span style=\"color: #333;font-weight: bold\">function<\/span> (response){\r\n\r\n  <span style=\"color: #333;font-weight: bold\">var<\/span> optionsArray = [];\r\n  <span style=\"color: #998;font-style: italic\">\/\/ Create a LayerDrawingOptions object used to set<\/span>\r\n  <span style=\"color: #998;font-style: italic\">\/\/ a renderer on a sublayer of a DynamicLayer<\/span>\r\n  <span style=\"color: #333;font-weight: bold\">var<\/span> drawingOptions = <span style=\"color: #333;font-weight: bold\">new<\/span> LayerDrawingOptions();\r\n  <span style=\"color: #998;font-style: italic\">\/\/ Set the response renderer on the drawing options<\/span>\r\n  drawingOptions.renderer = response.renderer;\r\n\r\n  <span style=\"color: #998;font-style: italic\">\/\/ And place the drawing options in index 3 so it applies to the states sublayer<\/span>\r\n  optionsArray[<span style=\"color: #008080\">3<\/span>] = drawingOptions;\r\n  <span style=\"color: #998;font-style: italic\">\/\/ set the renderer on the layer<\/span>\r\n  censusMapServiceLayer.setLayerDrawingOptions(optionsArray);\r\n});\r\n<\/pre>\n<p><a href=\"https:\/\/github.com\/ekenes\/esri-js-samples\/blob\/master\/smart-mapping\/dynamic-layer-join.html#L330-L374\"><strong>View the code on GitHub<\/strong><\/a><\/p>\n<h2>Conclusion<\/h2>\n<p>This sample adds an ArcGISDynamicMapServiceLayer instance to the map and updates its visible layer(s) and symbology on the fly using a renderer generated from the SmartMapping module. This allows you to explore data from joined tables in dynamic workspaces and change the visualization of a dynamic layer. Keep in mind that not all renderers generated by the SmartMapping module, including <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/esri.renderers.smartmapping-amd.html#createcolorrenderer\">continuous color<\/a> and <a href=\"https:\/\/developers.arcgis.com\/javascript\/3\/jsapi\/esri.renderers.smartmapping-amd.html#createsizerenderer\">continuous size<\/a>, cannot be used in the current version of MapServer. Support for applying these renderers to dynamic layers is planned for future releases. <\/p>\n<p>The snippets provided above represent the most essential pieces of code needed for this workflow to function. Review the <a href=\"https:\/\/github.com\/ekenes\/esri-js-samples\/blob\/master\/smart-mapping\/dynamic-layer-join.html\">code<\/a> of the <a href=\"https:\/\/ekenes.github.io\/esri-js-samples\/smart-mapping\/dynamic-layer-join.html\">app<\/a> to see each of these pieces in context.<\/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":"","card_image":false,"wide_image":false},"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>Smart Mapping with dynamic workspaces<\/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\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Smart Mapping with dynamic workspaces\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces\" \/>\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=\"2018-05-25T22:42:20+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\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces\"},\"author\":{\"name\":\"Kristian Ekenes\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/5469f723fbfb78138efbb1da56e6aa9b\"},\"headline\":\"Smart Mapping with dynamic workspaces\",\"datePublished\":\"2016-05-25T06:00:32+00:00\",\"dateModified\":\"2018-05-25T22:42:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces\"},\"wordCount\":5,\"publisher\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\"},\"keywords\":[\"cartographic design\",\"color\",\"dynamic layers\",\"JavaScript\",\"rendering\",\"smart mapping\",\"web\",\"workspace\"],\"articleSection\":[\"Mapping\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces\",\"name\":\"Smart Mapping with dynamic workspaces\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#website\"},\"datePublished\":\"2016-05-25T06:00:32+00:00\",\"dateModified\":\"2018-05-25T22:42:20+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.esri.com\/arcgis-blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Smart Mapping with dynamic workspaces\"}]},{\"@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":"Smart Mapping with dynamic workspaces","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\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces","og_locale":"en_US","og_type":"article","og_title":"Smart Mapping with dynamic workspaces","og_url":"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces","og_site_name":"ArcGIS Blog","article_publisher":"https:\/\/www.facebook.com\/esrigis\/","article_modified_time":"2018-05-25T22:42:20+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\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces#article","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces"},"author":{"name":"Kristian Ekenes","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/5469f723fbfb78138efbb1da56e6aa9b"},"headline":"Smart Mapping with dynamic workspaces","datePublished":"2016-05-25T06:00:32+00:00","dateModified":"2018-05-25T22:42:20+00:00","mainEntityOfPage":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces"},"wordCount":5,"publisher":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization"},"keywords":["cartographic design","color","dynamic layers","JavaScript","rendering","smart mapping","web","workspace"],"articleSection":["Mapping"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces","url":"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces","name":"Smart Mapping with dynamic workspaces","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#website"},"datePublished":"2016-05-25T06:00:32+00:00","dateModified":"2018-05-25T22:42:20+00:00","breadcrumb":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/mapping\/mapping\/smart-mapping-with-dynamic-workspaces#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.esri.com\/arcgis-blog\/"},{"@type":"ListItem","position":2,"name":"Smart Mapping with dynamic workspaces"}]},{"@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":"May 25, 2016","author_name":"Kristian Ekenes","author_page":"https:\/\/www.esri.com\/arcgis-blog\/author\/kekenes","custom_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/08\/Newsroom-Keyart-Wide-1920-x-1080.jpg","primary_product":"ArcGIS Maps SDK for JavaScript","tag_data":[{"term_id":23201,"name":"cartographic design","slug":"cartographic-design","term_group":0,"term_taxonomy_id":23201,"taxonomy":"post_tag","description":"","parent":0,"count":332,"filter":"raw"},{"term_id":30791,"name":"color","slug":"color","term_group":0,"term_taxonomy_id":30791,"taxonomy":"post_tag","description":"","parent":0,"count":31,"filter":"raw"},{"term_id":30801,"name":"dynamic layers","slug":"dynamic-layers","term_group":0,"term_taxonomy_id":30801,"taxonomy":"post_tag","description":"","parent":0,"count":5,"filter":"raw"},{"term_id":24921,"name":"JavaScript","slug":"javascript","term_group":0,"term_taxonomy_id":24921,"taxonomy":"post_tag","description":"","parent":0,"count":151,"filter":"raw"},{"term_id":29541,"name":"rendering","slug":"rendering","term_group":0,"term_taxonomy_id":29541,"taxonomy":"post_tag","description":"","parent":0,"count":17,"filter":"raw"},{"term_id":24581,"name":"smart mapping","slug":"smart-mapping","term_group":0,"term_taxonomy_id":24581,"taxonomy":"post_tag","description":"","parent":0,"count":81,"filter":"raw"},{"term_id":29401,"name":"web","slug":"web","term_group":0,"term_taxonomy_id":29401,"taxonomy":"post_tag","description":"","parent":0,"count":17,"filter":"raw"},{"term_id":30811,"name":"workspace","slug":"workspace","term_group":0,"term_taxonomy_id":30811,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"}],"category_data":[{"term_id":22941,"name":"Mapping","slug":"mapping","term_group":0,"term_taxonomy_id":22941,"taxonomy":"category","description":"","parent":0,"count":2690,"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":362,"filter":"raw"},{"term_id":36601,"name":"Developers","slug":"developers","term_group":0,"term_taxonomy_id":36601,"taxonomy":"product","description":"","parent":0,"count":763,"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\/72001","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=72001"}],"version-history":[{"count":0,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/72001\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/media?parent=72001"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/categories?post=72001"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/tags?post=72001"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/industry?post=72001"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/product?post=72001"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}