In the 4.5 release of the ArcGIS API for JavaScript, autocasting support was expanded to all renderers, symbols, and symbol layers. This means that symbols and renderers can be created programmatically without importing their modules. All you need to do is create a simple object, specify the symbol type, and set the desired properties; then the API will autocast the object to its proper class. The samples in the API documentation were updated to consistently follow this new pattern, which cleans up the lists of required modules quite nicely.
Let’s look at an example where we set a renderer with a 3D symbol, labels, and callouts on a FeatureLayer:
To achieve this prior to 4.5 we needed to import six modules for the renderer, symbol, symbol layer, label symbol, text symbol layer, and the callout. The full list of required module imports looks like this:
require([ "esri/WebScene", "esri/views/SceneView", "esri/layers/FeatureLayer", "esri/renderers/SimpleRenderer", "esri/symbols/PointSymbol3D", "esri/symbols/IconSymbol3DLayer", "esri/symbols/LabelSymbol3D", "esri/symbols/TextSymbol3DLayer", "esri/symbols/callouts/LineCallout3D", "dojo/domReady!" ], function( WebScene, SceneView, FeatureLayer, SimpleRenderer, PointSymbol3D, IconSymbol3DLayer, LabelSymbol3D, TextSymbol3DLayer, LineCallout3D ){ // use modules here });
With this new workflow, you don’t need to import modules for the renderers and the symbols. So in the example above, you only need to import the WebScene, SceneView and FeatureLayer:
require([ "esri/WebScene", "esri/views/SceneView", "esri/layers/FeatureLayer", "dojo/domReady!" ], function( WebScene, SceneView, FeatureLayer ){ // use modules here });
But how do we actually define the renderer and symbol objects without the required modules? We do this by specifying their type in a JavaScript object, just like in the example below:
If you want to play with the examples yourself, here’s the code snippet for using classes and here’s the code snippet for using types. These snippets were derived from the Point styles for cities sample in the documentation.
Similarly, you can now autocast all geometries added to graphics. For example, instead of importing esri/geometry/Polyline
when manually creating a line, you can skip the import and do the following:
var polylineGraphic = new Graphic({ geometry: { type: "polyline", // autocasts as new Polyline() paths: [ [-0.178, 51.48791, 0], [-0.178, 51.48791, 1000] ] }, symbol: { type: "simple-line", // autocasts as SimpleLineSymbol() color: [226, 119, 40], width: 4 } });
The Add Graphics to SceneView and Intro to Graphics samples were updated to follow the autocasting pattern.
When specifying object types is required
For many properties, you don’t need to specify the type of object to autocast since the API already knows the expected type. For example, you don’t need to set a type property in an object representing SimpleMarkerSymbol.outline because the expected type for the outline of a simple marker (and all other symbols) is SimpleLineSymbol.
However, renderer, symbol, symbol layer, and geometry objects are usually passed as values to polymorphic properties, meaning the API doesn’t know how to autocast the object unless the type is explicitly specified. The snippet below demonstrates both scenarios in context:
layer.renderer = { // type must be specified since // 1 of 3 renderer types could be applied here type: "simple", symbol: { // the type must also be specified for symbol properties of a renderer // since 1 of 10 symbol types could be used type: "simple-marker", outline: { // Specifying type for outlines is not necessary // since `simple-line` is the only expected type style: "dash-dot", color: [ 255, 128, 45 ] } } };
So how do you know the value of the type property for any given scenario? There are number of ways to find the required type value. You can…
- Find the type in the documentation,
- Use the Symbol Playground to configure the code and copy the autocastable snippet for immediate use in your app, or
- Infer the value.
Generally, you can infer the type by removing the generic text from the desired class name and kebabifying it. For example, SimpleFillSymbol.type is simple-fill
(note that symbol is removed because it is used in all related 2D symbol class names). Another example: UniqueValueRenderer.type is unique-value
(there’s no need to specify renderer in the type). IconSymbol3DLayer.type is icon
(the Symbol3DLayer bit is common among all symbol layers). See the comprehensive tables below to more fully understand this pattern. Once you’re familiar with it, you won’t have to look it up in the documentation!
We’d love to hear what you think of this change or any other suggestions related to coding workflows.
Happy coding!
The ArcGIS API for JavaScript team
Class type tables
Renderer class name | Type |
---|---|
ClassBreaksRenderer | class-breaks |
SimpleRenderer | simple |
UniqueValueRenderer | unique-value |
PointCloudRGBRenderer | point-cloud-rgb |
PointCloudClassBreaksRenderer | point-cloud-class-breaks |
PointCloudUniqueValueRenderer | point-cloud-unique-value |
PointCloudStretchRenderer | point-cloud-stretch |
2D Symbol class name | Type |
---|---|
PictureMarkerSymbol | picture-marker |
PictureFillSymbol | picture-fill |
SimpleFillSymbol | simple-fill |
SimpleLineSymbol | simple-line |
SimpleMarkerSymbol | simple-marker |
TextSymbol | text |
3D Symbol/symbol layer class name | Type |
---|---|
LineCallout3D | line |
ExtrudeSymbol3DLayer | extrude |
FillSymbol3DLayer | fill |
IconSymbol3DLayer | icon |
LabelSymbol3D | label-3d |
LineSymbol3D | line-3d |
LineSymbol3DLayer | line |
MeshSymbol3D | mesh-3d |
ObjectSymbol3DLayer | object |
PathSymbol3DLayer | path |
PointSymbol3D | point-3d |
PolygonSymbol3D | polygon-3d |
TextSymbol3DLayer | text |
WebStyleSymbol | web-style |
Geometry class name | Type |
---|---|
Multipoint | multipoint |
Point | point |
Polygon | fill |
Polyline | polyline |
Commenting is not enabled for this article.