Select to view content in your preferred language

ArcGIS API for JavaScript 4.25 and 3.42

1445
1
11-10-2022 05:51 AM
Noah-Sager
Esri Regular Contributor
2 1 1,445

Preface

When I was little, I dreamed of one day writing a geospatial web API release blog. But this isn’t a cooking/recipe blog, so let’s get started.

 

Introduction

Welcome to the release of versions 4.25 and 3.42 of the ArcGIS API for JavaScript. Here are some 4.25 highlights (please refer to the 3.42 link at the end for 3.x updates). I also inserted another song parody towards the end of this blog, if you're into that sort of thing. We fixed 34 bugs, made 19 enhancements, and added or updated 14 samples. 

 

Chapter 1. Ready to launch

Cluster blockbuster

We now allow you to override the default style of point clusters with either a dedicated cluster symbol or a renderer. By default, clusters are styled based on the layer's renderer so that the cluster symbol either represents the average value of the features in the cluster, or the most common category.

clusterBlockbuster.png

https://developers.arcgis.com/javascript/latest/release-notes/ - custom-cluster-styles

 

Related record scratch

Displaying related records in Popups has never been easier (or possible) using the new RelationshipContent content type in PopupTemplate. When configuring RelationshipContent, the related layer or table must be added to the map. Support for editing related records will be added in a later release.

relatedRecordsPopup.png

https://developers.arcgis.com/javascript/latest/sample-code/popuptemplate-browse-related-records/

 

All three dimensions

4.25 offers some first-class SceneView updates as well.

Drill deeper into the rich data of VoxelLayer with new properties. There are two approaches to conveniently display different isosurfaces. For continuous variables, you can define a transferFunction to apply normalized color or transparency stops. For discrete variables, you can set a color for each variable.

Add dimensioning to display lengths and distances. LengthDimensions can be created interactively or programmatically. You can also save dimensions to a WebScene.

Lastly, snap to existing features now in all three dimensions to derive complete x, y, and z coordinates from existing features. This also adds 3D Object and Building Scene Layers to available SnappingOptions.

3d-dimensioning.gif

https://developers.arcgis.com/javascript/latest/release-notes/#3d-updates

 

Chapter 2. Caesura

Letter to the Editor

The FeatureForm widget now allows you to access data from other layers. That means you can derive values based on another layer. The FeatureTable widget now supports deleting selected features via the deleteSelection method. For the method to be successful, there must be at least one selected row in the table, editingEnabled must be true, and the underlying data must support deletion.

FeatureLayer was updated to propagate edits to other layers affected by a single edit. This means that edits to other layers that are a result of attribute rules or composite relationships will now cause the layers affected to refresh and render the updated features. Pretty sweet, right?

editor.gif

https://developers.arcgis.com/javascript/latest/release-notes/#editing-updates

 

Layer Potpourri

We added support for ControlPointsGeoreference on MediaLayer. An image or video can now be positioned, scaled, and rotated with two control points. Additionally, it will be skewed with three control points. With four control points, a perspective transformation is applied to the element.

https://developers.arcgis.com/javascript/latest/sample-code/layers-medialayer-control-points/

We enhanced MapImageLayer to highlight the selected feature when displaying its Popup.

https://developers.arcgis.com/javascript/latest/sample-code/layers-dynamicdatalayer-table-join/

You can set multidimensionalSubset on ImageryLayer and ImageryTileLayer to expose only subset of dimensional slices that meet the requirements of the multidimensionalSubset. This release also adds beta support for adding Cloud Optimized GeoTiff (COG) files to an ImageryTileLayer via the URL property. COG files can take advantage of all the capabilities of ImageryTileLayer.

CSVLayer and GeoJSONLayer can be loaded from csv and geojson portal items respectively by either setting portalItem.id on the layer or via Layer.fromPortalItem() method.

A SubtypeGroupLayer can now be loaded from a WebMap published with a subtype group layer. Properties like the renderer will be respected for each sublayer when the layer is loaded from a web map. Additionally, the Legend widget added support for SubtypeGroupLayer.

Potpourri.png

 

Open Access

For increased accessibility, we made many improvements for better color contrasts in CSS themes, better use of ARIA roles and attributes, and various other changes. This makes both for a better experience with screen readers, but also for users in general. We plan to continue to improve accessibility in our API in upcoming releases.

https://developers.arcgis.com/javascript/latest/release-notes/ - widget-updates

 

Chapter 3. Penultimates

If you’ve knowledge, you’ve knowledge

KnowledgeGraphService (beta) is a new class that connects to existing ArcGIS Enterprise knowledge graph services. A knowledge graph service is composed of a knowledge graph, which contains entities and relationships and the data model that defines the entity types and relationship types in the graph. A knowledge graph service allows users to search, query, and edit the knowledge graph.

KnowledgeGraphService.png

https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-knowledgeGraphService.html

 

Bloggers

There are many wonderful contributions that help explain or showcase concepts related to the ArcGIS API for JavaScript. To emphasize these efforts, we've created a new Blogs page that offers a curated list of relevant blogs organized by concepts.

Within each concept, there is a list of blogs ordered by the corresponding version of the ArcGIS API for JavaScript at publication, with publication dates, and links to read the actual blogs. You can access this new page at the top right of the navigation bar.

https://developers.arcgis.com/javascript/latest/blogs/

 

Package undeliverable

The CDN on js.arcgis.com will no longer host the following AMD packages for version 4.25 and later: dgrid, dijit, dojo, dojox, dstore, and tslib. API versions 4.24 and earlier will continue to include the packages. The Dojo loader will continue to be included, to allow for AMD support in the browser.

 

Post Script

Can I, can I put you on something like

“This is the ArcGIS API for JavaScript”,

Take four, point, twenty, five

 

Do you like, the ArcGIS API for JavaScript?

I like the ArcGIS API for JavaScript.

Don’t you like the ArcGIS API for JavaScript,

Customer?

 

I want to browse related records

I want them in a popup

I want to browse related records

Customer

 

Why use the new knowledge graph service?

I used the new knowledge graph service

Do you use entity-centric relationship data modeling and analysis

Customer?

 

MapImageLayer popups, they now highlight

But every time I load hundreds of MapImageLayers at night

They render so fast

They render so fast

Oh-oh, oh-oh, oh-oh

 

I need to load CSV and GeoJSON layers from a portal item,

Would you like to be able to try some?

Need to update to 4.25

Customer

 

They didn’t like the ArcGIS API for JavaScript

They never used the ArcGIS API for JavaScript

They didn’t know that we made many accessibility improvements

Customer

 

You’re born to read, I was born to write

But those JavaScript blogs are hard to find when the time is right

 

It reminds me of the new Blogs page (do you like the ArcGIS API for JavaScript?)

It reminds me of the new Blogs page (do you like the ArcGIS API for JavaScript?)

It reminds me of the new Blogs page

Oh-oh, oh-oh, oh-oh

 

Do you like, the ArcGIS API for JavaScript?

(We like the ArcGIS API for JavaScript)

I like the ArcGIS API for JavaScript

Customer

 

Do you like, the ArcGIS API for JavaScript?

(We like all kinds of JavaScript APIs)

But I like the ArcGIS API for JavaScript best

Customer

 

You’re born to read, I was born to write

But those JavaScript blogs are hard to find when the time is right

It reminds me of the new Blogs page (do you like the ArcGIS API for JavaScript?)

It reminds me of the new Blogs page (do you like the ArcGIS API for JavaScript?)

 

Acknowledgements

Release Blog

https://www.esri.com/arcgis-blog/products/js-api-arcgis/announcements/whats-new-in-arcgis-api-for-ja...

4.25 Release Notes

https://developers.arcgis.com/javascript/latest/guide/release-notes/index.html

4.25 Samples

https://developers.arcgis.com/javascript/latest/sample-code/?tagged=4.25

3.42 What’s New

https://developers.arcgis.com/javascript/3/jshelp/whats_new.html

Breaking Changes across all 4x releases

https://developers.arcgis.com/javascript/latest/guide/breaking-changes/index.html

Song inspiration

Violent Femmes - American Music

Fair use and Parody law

https://en.wikipedia.org/wiki/Fair_use

1 Comment
JoelBennett
MVP Regular Contributor

The new feature "Categorize unique values into groups" looks great, and I'd like to put it to use on some layers with redundant symbols, but have a few questions.

Background: in our products, we typically have a configuration file where admins specify what layers should be loaded into the map, as well as various settings related to those layers.  This includes the ability to specify renderer information, and we require that it be specified in JSON format, so that at runtime, the renderer can be instantiated via rendererJsonUtils.fromJSON, which works great for both 3.x and 4.x-based products.

There is no definitive reference to these JSON objects (structure, property names, etc) in the JavaScript API documentation, but there is here.  That page hasn't been updated for awhile though, and therefore doesn't include any information about how to specify the unique value groups supported by 4.25.

In order to figure out the JSON structure for these groups, I went to the new "Unique value groups with headings" sample, and added the following line to get the JSON:

console.info(JSON.stringify(layer.renderer.toJSON()));

 

I've added the output at the end of this post for reference.

Reverse engineering the structure in this way and designing against it seems like an unsafe idea since the structure is undocumented, and therefore possibly subject to arbitrary change.  Will the renderer JSON documentation be updated soon?  Are any changes to the new structure seen in 4.25 expected?

Looking at the output (below), I see that "uniqueValueGroups" and "uniqueValueInfos" are both specified, and therefore redundant, and I would like to keep my config files as small as possible.  If I removed the uniqueValueGroups, I would expect it to work the same as previously in both 3.x and 4.x.  On the other hand, I assume I can remove uniqueValueInfos and 4.25-based implementations would still have what's necessary in order to fully instantiate the renderer...is that true?

 

{
	"type": "uniqueValue",
	"field1": "zonecode",
	"uniqueValueGroups": [{
		"heading": "Commercial",
		"classes": [{
			"label": "C-1 | Neighborhood Commercial",
			"symbol": {
				"type": "esriSFS",
				"color": [189, 145, 145, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["C-1"]
			]
		}, {
			"label": "C-2 | Community Commercial",
			"symbol": {
				"type": "esriSFS",
				"color": [255, 179, 219, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["C-2"]
			]
		}, {
			"label": "C-3 | Major Commercial",
			"symbol": {
				"type": "esriSFS",
				"color": [255, 0, 0, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["C-3"]
			]
		}]
	}, {
		"heading": "Office",
		"classes": [{
			"label": "GO | General Office",
			"symbol": {
				"type": "esriSFS",
				"color": [176, 196, 222, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["GO"]
			]
		}, {
			"label": "E-1 | Campus Employment",
			"symbol": {
				"type": "esriSFS",
				"color": [230, 230, 230, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["E-1"]
			]
		}, {
			"label": "E-2 | Mixed Use Employment",
			"symbol": {
				"type": "esriSFS",
				"color": [255, 20, 255, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["E-2"]
			]
		}]
	}, {
		"heading": "Residential",
		"classes": [{
			"label": "R-1 | Low-Density Residential",
			"symbol": {
				"type": "esriSFS",
				"color": [255, 255, 224, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["R-1"]
			]
		}, {
			"label": "R-1.5 | Rowhouse",
			"symbol": {
				"type": "esriSFS",
				"color": [255, 255, 0, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["R-1.5"]
			]
		}, {
			"label": "R-2 | Medium-Density Residential",
			"symbol": {
				"type": "esriSFS",
				"color": [240, 230, 140, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["R-2"]
			]
		}, {
			"label": "R-3 | Limited High-Density Residential",
			"symbol": {
				"type": "esriSFS",
				"color": [255, 214, 0, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["R-3"]
			]
		}, {
			"label": "R-4 | High-Density Residential",
			"symbol": {
				"type": "esriSFS",
				"color": [255, 166, 0, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["R-4"]
			]
		}]
	}, {
		"heading": "Industrial",
		"classes": [{
			"label": "I-2 | Light-Medium Industrial",
			"symbol": {
				"type": "esriSFS",
				"color": [219, 112, 214, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["I-2"]
			]
		}, {
			"label": "I-3 | Heavy Industrial",
			"symbol": {
				"type": "esriSFS",
				"color": [148, 112, 219, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["I-3"]
			]
		}]
	}, {
		"heading": "Open Space",
		"classes": [{
			"label": "NR | Natural Resource",
			"symbol": {
				"type": "esriSFS",
				"color": [125, 252, 0, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["NR"]
			]
		}, {
			"label": "PRO | Park, Recreation & Open Space",
			"symbol": {
				"type": "esriSFS",
				"color": [0, 255, 128, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["PRO"]
			]
		}]
	}, {
		"heading": "Other",
		"classes": [{
			"label": "AG | Agricultural",
			"symbol": {
				"type": "esriSFS",
				"color": [219, 166, 33, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["AG"]
			]
		}, {
			"label": "PL | Public Land",
			"symbol": {
				"type": "esriSFS",
				"color": [0, 191, 255, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["PL"]
			]
		}, {
			"label": "S | Special Area",
			"symbol": {
				"type": "esriSFS",
				"color": [161, 237, 237, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["S-DW"],
				["S-DR"],
				["S-RP"],
				["S-JW"],
				["S-RN"],
				["S-WS"],
				["S-CN"],
				["S-HB"],
				["S-F"],
				["S-W"],
				["S-E"],
				["S-C"]
			]
		}, {
			"label": "S-H | Historic",
			"symbol": {
				"type": "esriSFS",
				"color": [0, 0, 204, 255],
				"style": "esriSFSSolid"
			},
			"values": [
				["S-H"]
			]
		}]
	}],
	"uniqueValueInfos": [{
		"label": "C-1 | Neighborhood Commercial",
		"symbol": {
			"type": "esriSFS",
			"color": [189, 145, 145, 255],
			"style": "esriSFSSolid"
		},
		"value": "C-1"
	}, {
		"label": "C-2 | Community Commercial",
		"symbol": {
			"type": "esriSFS",
			"color": [255, 179, 219, 255],
			"style": "esriSFSSolid"
		},
		"value": "C-2"
	}, {
		"label": "C-3 | Major Commercial",
		"symbol": {
			"type": "esriSFS",
			"color": [255, 0, 0, 255],
			"style": "esriSFSSolid"
		},
		"value": "C-3"
	}, {
		"label": "GO | General Office",
		"symbol": {
			"type": "esriSFS",
			"color": [176, 196, 222, 255],
			"style": "esriSFSSolid"
		},
		"value": "GO"
	}, {
		"label": "E-1 | Campus Employment",
		"symbol": {
			"type": "esriSFS",
			"color": [230, 230, 230, 255],
			"style": "esriSFSSolid"
		},
		"value": "E-1"
	}, {
		"label": "E-2 | Mixed Use Employment",
		"symbol": {
			"type": "esriSFS",
			"color": [255, 20, 255, 255],
			"style": "esriSFSSolid"
		},
		"value": "E-2"
	}, {
		"label": "R-1 | Low-Density Residential",
		"symbol": {
			"type": "esriSFS",
			"color": [255, 255, 224, 255],
			"style": "esriSFSSolid"
		},
		"value": "R-1"
	}, {
		"label": "R-1.5 | Rowhouse",
		"symbol": {
			"type": "esriSFS",
			"color": [255, 255, 0, 255],
			"style": "esriSFSSolid"
		},
		"value": "R-1.5"
	}, {
		"label": "R-2 | Medium-Density Residential",
		"symbol": {
			"type": "esriSFS",
			"color": [240, 230, 140, 255],
			"style": "esriSFSSolid"
		},
		"value": "R-2"
	}, {
		"label": "R-3 | Limited High-Density Residential",
		"symbol": {
			"type": "esriSFS",
			"color": [255, 214, 0, 255],
			"style": "esriSFSSolid"
		},
		"value": "R-3"
	}, {
		"label": "R-4 | High-Density Residential",
		"symbol": {
			"type": "esriSFS",
			"color": [255, 166, 0, 255],
			"style": "esriSFSSolid"
		},
		"value": "R-4"
	}, {
		"label": "I-2 | Light-Medium Industrial",
		"symbol": {
			"type": "esriSFS",
			"color": [219, 112, 214, 255],
			"style": "esriSFSSolid"
		},
		"value": "I-2"
	}, {
		"label": "I-3 | Heavy Industrial",
		"symbol": {
			"type": "esriSFS",
			"color": [148, 112, 219, 255],
			"style": "esriSFSSolid"
		},
		"value": "I-3"
	}, {
		"label": "NR | Natural Resource",
		"symbol": {
			"type": "esriSFS",
			"color": [125, 252, 0, 255],
			"style": "esriSFSSolid"
		},
		"value": "NR"
	}, {
		"label": "PRO | Park, Recreation & Open Space",
		"symbol": {
			"type": "esriSFS",
			"color": [0, 255, 128, 255],
			"style": "esriSFSSolid"
		},
		"value": "PRO"
	}, {
		"label": "AG | Agricultural",
		"symbol": {
			"type": "esriSFS",
			"color": [219, 166, 33, 255],
			"style": "esriSFSSolid"
		},
		"value": "AG"
	}, {
		"label": "PL | Public Land",
		"symbol": {
			"type": "esriSFS",
			"color": [0, 191, 255, 255],
			"style": "esriSFSSolid"
		},
		"value": "PL"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-DW"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-DR"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-RP"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-JW"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-RN"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-WS"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-CN"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-HB"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-F"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-W"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-E"
	}, {
		"label": "S | Special Area",
		"symbol": {
			"type": "esriSFS",
			"color": [161, 237, 237, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-C"
	}, {
		"label": "S-H | Historic",
		"symbol": {
			"type": "esriSFS",
			"color": [0, 0, 204, 255],
			"style": "esriSFSSolid"
		},
		"value": "S-H"
	}]
}

 

About the Author
Noah Sager is a Product Engineer on the ArcGIS Maps SDK for JavaScript team at Esri. Prior to joining Esri, he mapped utility lines around Appalachia, investigated public restroom access in Chicago, and studied foraging behavior in squirrels in Canada.