ArcGIS Visualization
Use this skill when styling layers with renderers, symbols, visual variables, labels, and effects.
Import Patterns
Direct ESM Imports
import SimpleRenderer from "@arcgis/core/renderers/SimpleRenderer.js";
import UniqueValueRenderer from "@arcgis/core/renderers/UniqueValueRenderer.js";
import ClassBreaksRenderer from "@arcgis/core/renderers/ClassBreaksRenderer.js";
import SimpleMarkerSymbol from "@arcgis/core/symbols/SimpleMarkerSymbol.js";
import SimpleLineSymbol from "@arcgis/core/symbols/SimpleLineSymbol.js";
import SimpleFillSymbol from "@arcgis/core/symbols/SimpleFillSymbol.js";
CDN Dynamic Imports
const [SimpleRenderer, SimpleMarkerSymbol] = await $arcgis.import([
"@arcgis/core/renderers/SimpleRenderer.js",
"@arcgis/core/symbols/SimpleMarkerSymbol.js"
]);
Note: Examples below use autocasting (plain objects with
type). For CDN usage, replaceimport X from "path"withconst X = await $arcgis.import("path").
Renderer Types Overview
| Renderer | Autocast Type | Use Case |
|----------|---------------|----------|
| SimpleRenderer | "simple" | Same symbol for all features |
| UniqueValueRenderer | "unique-value" | Different symbols by category |
| ClassBreaksRenderer | "class-breaks" | Different symbols by numeric ranges |
| HeatmapRenderer | "heatmap" | Density visualization (points only) |
| DotDensityRenderer | "dot-density" | Dot density maps (polygons only) |
| PieChartRenderer | "pie-chart" | Pie charts per feature |
| DictionaryRenderer | "dictionary" | Military symbology (MIL-STD-2525) |
| FlowRenderer | "flow" | Animated flow lines (imagery) |
SimpleRenderer
const renderer = {
type: "simple",
symbol: {
type: "simple-marker",
color: "blue",
size: 8,
outline: {
color: "white",
width: 1
}
}
};
layer.renderer = renderer;
With Visual Variables
const renderer = {
type: "simple",
symbol: {
type: "simple-marker",
color: "#13EB0C",
outline: { color: "#A9A9A9", width: 0.5 }
},
visualVariables: [{
type: "size",
field: "population",
stops: [
{ value: 1000, size: 4 },
{ value: 10000, size: 12 },
{ value: 100000, size: 24 }
]
}]
};
UniqueValueRenderer
Basic Unique Values
const renderer = {
type: "unique-value",
field: "type",
defaultSymbol: { type: "simple-fill", color: "gray" },
uniqueValueInfos: [
{
value: "residential",
symbol: { type: "simple-fill", color: "#FFFF00" },
label: "Residential"
},
{
value: "commercial",
symbol: { type: "simple-fill", color: "#FF0000" },
label: "Commercial"
},
{
value: "industrial",
symbol: { type: "simple-fill", color: "#800080" },
label: "Industrial"
}
]
};
Grouped Unique Values (with headings in legend)
const renderer = {
type: "unique-value",
field: "zonecode",
uniqueValueGroups: [
{
heading: "Commercial",
classes: [
{
label: "C-1 | Neighborhood Commercial",
symbol: createFillSymbol([189, 145, 145]),
values: "C-1"
},
{
label: "C-2 | Community Commercial",
symbol: createFillSymbol([255, 179, 219]),
values: "C-2"
}
]
},
{
heading: "Residential",
classes: [
{
label: "R-1 | Low Density",
symbol: createFillSymbol([255, 255, 224]),
values: "R-1"
},
{
label: "Special Areas",
symbol: createFillSymbol([161, 237, 237]),
values: ["S-DW", "S-DR", "S-RP"] // Multiple values
}
]
}
]
};
function createFillSymbol(color) {
return {
type: "simple-fill",
color: color,
outline: null
};
}
ClassBreaksRenderer
const renderer = {
type: "class-breaks",
field: "population",
normalizationField: "area", // Optional: divide by this field
legendOptions: {
title: "Population Density"
},
defaultSymbol: {
type: "simple-fill",
color: "black",
style: "backward-diagonal"
},
defaultLabel: "No data",
classBreakInfos: [
{
minValue: 0,
maxValue: 100,
symbol: { type: "simple-fill", color: "#fffcd4" },
label: "< 100"
},
{
minValue: 100,
maxValue: 500,
symbol: { type: "simple-fill", color: "#b1cdc2" },
label: "100 - 500"
},
{
minValue: 500,
maxValue: 1000,
symbol: { type: "simple-fill", color: "#38627a" },
label: "500 - 1,000"
},
{
minValue: 1000,
maxValue: Infinity,
symbol: { type: "simple-fill", color: "#0d2644" },
label: "> 1,000"
}
]
};
HeatmapRenderer
const renderer = {
type: "heatmap",
colorStops: [
{ color: "rgba(63, 40, 102, 0)", ratio: 0 },
{ color: "#472b77", ratio: 0.083 },
{ color: "#563098", ratio: 0.25 },
{ color: "#7139d4", ratio: 0.5 },
{ color: "#853fff", ratio: 0.664 },
{ color: "#c29f80", ratio: 0.83 },
{ color: "#ffff00", ratio: 1 }
],
maxDensity: 0.01,
minDensity: 0,
radius: 18 // Blur radius in pixels
};
PieChartRenderer
const renderer = {
type: "pie-chart",
attributes: [
{ field: "asian_pop", label: "Asian", color: "#ed5151" },
{ field: "black_pop", label: "Black", color: "#149ece" },
{ field: "white_pop", label: "White", color: "#a7c636" },
{ field: "other_pop", label: "Other", color: "#9e559c" }
],
size: 18,
othersCategory: {
threshold: 0.05,
color: "gray",
label: "Other"
}
};
2D Symbol Types
SimpleMarkerSymbol (Points)
const symbol = {
type: "simple-marker",
style: "circle", // circle, square, cross, x, diamond, triangle
color: [255, 0, 0],
size: 12,
outline: {
color: [255, 255, 255],
width: 2
}
};
SimpleLineSymbol
const symbol = {
type: "simple-line",
style: "solid", // solid, dash, dot, dash-dot, etc.
color: [0, 0, 255],
width: 2,
cap: "round", // round, butt, square
join: "round" // round, miter, bevel
};
SimpleFillSymbol (Polygons)
const symbol = {
type: "simple-fill",
style: "solid", // solid, none, horizontal, vertical, cross, etc.
color: [255, 255, 0, 0.5], // RGBA
outline: {
type: "simple-line",
color: [0, 0, 0],
width: 1
}
};
PictureMarkerSymbol
const symbol = {
type: "picture-marker",
url: "https://example.com/icon.png",
width: 24,
height: 24,
xoffset: 0,
yoffset: 0
};
TextSymbol
const symbol = {
type: "text",
text: "Label",
color: "white",
font: {
family: "Arial",
size: 12,
weight: "bold"
},
haloColor: "black",
haloSize: 1
};
3D Symbol Types
PointSymbol3D
// Icon marker
const symbol = {
type: "point-3d",
symbolLayers: [{
type: "icon",
resource: { primitive: "circle" },
material: { color: "red" },
size: 12
}]
};
// Object marker
const objectSymbol = {
type: "point-3d",
symbolLayers: [{
type: "object",
resource: { primitive: "cylinder" }, // cone, cube, sphere, diamond
material: { color: "blue" },
height: 100,
width: 10,
depth: 10
}]
};
WebStyleSymbol (3D icons from gallery)
const symbol = {
type: "web-style",
name: "Pushpin 1",
styleName: "Esri2DPointSymbolsStyle"
};
MeshSymbol3D (for SceneLayer)
const symbol = {
type: "mesh-3d",
symbolLayers: [{
type: "fill",
material: { color: [244, 247, 134] }
}]
};
LineSymbol3D
const symbol = {
type: "line-3d",
symbolLayers: [{
type: "path",
profile: "quad", // circle, quad
material: { color: "red" },
width: 5,
height: 5
}]
};
PolygonSymbol3D
const symbol = {
type: "polygon-3d",
symbolLayers: [{
type: "extrude",
material: { color: "blue" },
size: 100 // Extrusion height
}]
};
Visual Variables
Visual variable classes: ColorVariable, SizeVariable, OpacityVariable, RotationVariable.
import ColorVariable from "@arcgis/core/renderers/visualVariables/ColorVariable.js";
import SizeVariable from "@arcgis/core/renderers/visualVariables/SizeVariable.js";
Size Variable
visualVariables: [{
type: "size",
field: "magnitude",
stops: [
{ value: 1, size: 4 },
{ value: 5, size: 20 },
{ value: 10, size: 40 }
]
}]
Color Variable
visualVariables: [{
type: "color",
field: "temperature",
stops: [
{ value: 0, color: "blue" },
{ value: 50, color: "yellow" },
{ value: 100, color: "red" }
]
}]
Opacity Variable
visualVariables: [{
type: "opacity",
field: "confidence",
stops: [
{ value: 0, opacity: 0.1 },
{ value: 100, opacity: 1 }
]
}]
Rotation Variable
visualVariables: [{
type: "rotation",
field: "heading",
rotationType: "geographic" // or "arithmetic"
}]
Labeling
layer.labelingInfo = [{
symbol: {
type: "text",
color: "white",
font: {
family: "Noto Sans",
size: 10,
weight: "bold"
},
haloColor: "#472b77",
haloSize: 1
},
labelPlacement: "above-center", // Various placement options
labelExpressionInfo: {
expression: "$feature.name" // Arcade expression
},
where: "population > 10000", // SQL filter
minScale: 500000,
maxScale: 0
}];
layer.labelsVisible = true;
Label Placements
- Points:
above-center,below-center,center-center,above-left, etc. - Lines:
above-along,below-along,center-along - Polygons:
always-horizontal
Arcade Label Expressions
labelExpressionInfo: {
expression: `
var pop = $feature.population;
if (pop > 1000000) {
return $feature.name + " (" + Round(pop/1000000, 1) + "M)";
}
return $feature.name;
`
}
Autocasting
All symbol and renderer objects support autocasting - use plain objects instead of constructing classes.
// Autocast: plain object with type property
layer.renderer = {
type: "simple",
symbol: {
type: "simple-marker",
color: "red",
size: 8
}
};
For TypeScript, use as const or satisfies:
layer.renderer = {
type: "simple",
symbol: {
type: "simple-marker",
color: "red",
size: 8
}
} as const;
When you need instance methods, use explicit classes:
import SimpleRenderer from "@arcgis/core/renderers/SimpleRenderer.js";
import SimpleMarkerSymbol from "@arcgis/core/symbols/SimpleMarkerSymbol.js";
layer.renderer = new SimpleRenderer({
symbol: new SimpleMarkerSymbol({ color: "red", size: 8 })
});
For layer effects (bloom, blur, drop-shadow) and blend modes, see
arcgis-feature-effects.
For smart mapping renderers and data-driven visualization, see
arcgis-smart-mapping.
For advanced cartographic symbols with CIM, see
arcgis-cim-symbols.
Reference Samples
get-started-visualization- Getting started with data visualizationvisualization-classbreaks- ClassBreaksRenderer for numeric datavisualization-unique-value-groups- Grouped unique value renderersvisualization-vv-color- Visual variables with colorvisualization-pie-chart- PieChartRenderer for multivariate datavisualization-heatmap- Heatmap visualizationvisualization-dot-density- Dot density mapsvisualization-point-styles- Point symbol styleslabels-basic- Basic label configurationlabels-multiline- Multiline labelslabels-multiple-classes- Multiple label classes
Common Pitfalls
-
Missing type property: Both renderers and symbols require a
typeproperty for autocasting.// Anti-pattern: missing type on renderer and symbol layer.renderer = { symbol: { color: "red", size: 8 } };// Correct: include type at both renderer and symbol level layer.renderer = { type: "simple", symbol: { type: "simple-marker", color: "red", size: 8 } };Impact: Without
type, autocasting fails silently. Features render with default symbology. -
Color formats: Colors can be hex, named, RGB array, or RGBA array.
color: "red" color: "#FF0000" color: [255, 0, 0] color: [255, 0, 0, 0.5] // With transparency -
Visual variables require numeric fields: Using a string field for size or color produces no variation.
// Anti-pattern: string field for size visualVariables: [{ type: "size", field: "city_name", // String field - no variation stops: [{ value: 0, size: 4 }, { value: 100, size: 40 }] }]// Correct: numeric field for size visualVariables: [{ type: "size", field: "population", // Numeric field stops: [{ value: 10000, size: 4 }, { value: 1000000, size: 40 }] }] -
Label expressions are Arcade: Use Arcade syntax (
$feature.fieldName), not JavaScript. -
3D symbols need SceneView: PointSymbol3D, LineSymbol3D, PolygonSymbol3D only work in SceneView, not MapView.
Related Skills
arcgis-cim-symbols- Advanced cartographic symbols (CIM)arcgis-smart-mapping- Auto-generated renderers from dataarcgis-feature-effects- Visual effects and filtersarcgis-core-maps- Map and view setuparcgis-layers- Layer types and configuration