Style and render geographic data with renderers, symbols, and visual variables. Use for creating thematic maps, heatmaps, class breaks, unique values, labels, and 3D visualization.
90
88%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
Use this skill when styling layers with renderers, symbols, visual variables, labels, and effects.
| Renderer | Use Case |
|---|---|
| SimpleRenderer | Same symbol for all features |
| UniqueValueRenderer | Different symbols by category |
| ClassBreaksRenderer | Different symbols by numeric ranges |
| HeatmapRenderer | Density visualization |
| DotDensityRenderer | Dot density maps |
| DictionaryRenderer | Military symbology |
const renderer = {
type: "simple",
symbol: {
type: "simple-marker",
color: "blue",
size: 8,
outline: {
color: "white",
width: 1
}
}
};
layer.renderer = renderer;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 }
]
}]
};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"
}
]
};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
};
}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"
}
]
};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
};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
}
};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
};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
}
};const symbol = {
type: "picture-marker",
url: "https://example.com/icon.png",
width: 24,
height: 24,
xoffset: 0,
yoffset: 0
};const symbol = {
type: "text",
text: "Label",
color: "white",
font: {
family: "Arial",
size: 12,
weight: "bold"
},
haloColor: "black",
haloSize: 1
};const symbol = {
type: "point-3d",
symbolLayers: [{
type: "icon",
resource: { primitive: "circle" },
material: { color: "red" },
size: 12
}]
};
// Object marker
const symbol = {
type: "point-3d",
symbolLayers: [{
type: "object",
resource: { primitive: "cylinder" }, // cone, cube, sphere, diamond
material: { color: "blue" },
height: 100,
width: 10,
depth: 10
}]
};const symbol = {
type: "web-style",
name: "Pushpin 1",
styleName: "Esri2DPointSymbolsStyle"
};const symbol = {
type: "mesh-3d",
symbolLayers: [{
type: "fill",
material: {
color: [244, 247, 134]
}
}]
};const symbol = {
type: "line-3d",
symbolLayers: [{
type: "path",
profile: "quad", // circle, quad
material: { color: "red" },
width: 5,
height: 5
}]
};const symbol = {
type: "polygon-3d",
symbolLayers: [{
type: "extrude",
material: { color: "blue" },
size: 100 // Extrusion height
}]
};visualVariables: [{
type: "size",
field: "magnitude",
stops: [
{ value: 1, size: 4 },
{ value: 5, size: 20 },
{ value: 10, size: 40 }
]
}]visualVariables: [{
type: "color",
field: "temperature",
stops: [
{ value: 0, color: "blue" },
{ value: 50, color: "yellow" },
{ value: 100, color: "red" }
]
}]visualVariables: [{
type: "opacity",
field: "confidence",
stops: [
{ value: 0, opacity: 0.1 },
{ value: 100, opacity: 1 }
]
}]visualVariables: [{
type: "rotation",
field: "heading",
rotationType: "geographic" // or "arithmetic"
}]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;above-center, below-center, center-center, above-left, etc.above-along, below-along, center-alongalways-horizontallabelExpressionInfo: {
expression: `
var pop = $feature.population;
if (pop > 1000000) {
return $feature.name + " (" + Round(pop/1000000, 1) + "M)";
}
return $feature.name;
`
}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.
All symbol and renderer objects support autocasting - you can use plain objects instead of constructing classes.
// This plain object autocasts to a SimpleRenderer with SimpleMarkerSymbol
layer.renderer = {
type: "simple",
symbol: {
type: "simple-marker",
color: "red",
size: 8
}
};// Use 'as const' to keep discriminated union types narrow
layer.renderer = {
type: "simple",
symbol: {
type: "simple-marker",
color: "red",
size: 8
}
} as const;
// Or use 'satisfies' for explicit type checking
layer.renderer = {
type: "simple",
symbol: {
type: "simple-marker",
color: "red",
size: 8
}
} satisfies __esri.SimpleRendererProperties;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
})
});Tip: Use autocasting for configuration-heavy code. Use explicit classes when you need instance methods or
instanceofchecks. See arcgis-core-maps skill for detailed guidance.
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 colorlabels-basic - Basic label configurationMissing type property: Both renderers and symbols require a type property for autocasting to work.
// Anti-pattern: missing type on renderer and symbol
layer.renderer = {
symbol: {
color: "red",
size: 8
}
};
// No type on renderer or symbol - autocasting fails silently// Correct: include type at both renderer and symbol level
layer.renderer = {
type: "simple",
symbol: {
type: "simple-marker",
color: "red",
size: 8
}
};Impact: Without the type property, the ArcGIS autocasting system cannot determine which class to create. The renderer or symbol is silently ignored, and features render with the default symbology or not at all.
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 transparencyVisual variables require numeric fields: Using a string field for a size or color visual variable produces no variation.
// Anti-pattern: using a string/text field for size visual variable
layer.renderer = {
type: "simple",
symbol: { type: "simple-marker", color: "blue" },
visualVariables: [{
type: "size",
field: "city_name", // String field - cannot map to size
minDataValue: 0,
maxDataValue: 100,
minSize: 4,
maxSize: 40
}]
};// Correct: use a numeric field for size visual variable
layer.renderer = {
type: "simple",
symbol: { type: "simple-marker", color: "blue" },
visualVariables: [{
type: "size",
field: "population", // Numeric field - maps correctly to size
minDataValue: 10000,
maxDataValue: 1000000,
minSize: 4,
maxSize: 40
}]
};Impact: All features render at the same default size with no visual variation. No error is thrown, making it difficult to diagnose why the visualization appears flat and uniform.
Label expressions are Arcade: Use Arcade syntax, not JavaScript
d84407b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.