arcgis-visualization

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.

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: arcgis-visualization
description: 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.
license: MIT
---

# ArcGIS Visualization

Use this skill when styling layers with renderers, symbols, visual variables, labels, and effects.

## Import Patterns

### Direct ESM Imports

```javascript
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

```javascript
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, replace `import X from "path"` with `const 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

```javascript
const renderer = {
  type: "simple",
  symbol: {
    type: "simple-marker",
    color: "blue",
    size: 8,
    outline: {
      color: "white",
      width: 1,
    },
  },
};

layer.renderer = renderer;
```

### With Visual Variables

```javascript
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

```javascript
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)

```javascript
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

```javascript
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

```javascript
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

```javascript
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)

```javascript
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

```javascript
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)

```javascript
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

```javascript
const symbol = {
  type: "picture-marker",
  url: "https://example.com/icon.png",
  width: 24,
  height: 24,
  xoffset: 0,
  yoffset: 0,
};
```

### TextSymbol

```javascript
const symbol = {
  type: "text",
  text: "Label",
  color: "white",
  font: {
    family: "Arial",
    size: 12,
    weight: "bold",
  },
  haloColor: "black",
  haloSize: 1,
};
```

## 3D Symbol Types

### PointSymbol3D

```javascript
// 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)

```javascript
const symbol = {
  type: "web-style",
  name: "Pushpin 1",
  styleName: "Esri2DPointSymbolsStyle",
};
```

### MeshSymbol3D (for SceneLayer)

```javascript
const symbol = {
  type: "mesh-3d",
  symbolLayers: [
    {
      type: "fill",
      material: { color: [244, 247, 134] },
    },
  ],
};
```

### LineSymbol3D

```javascript
const symbol = {
  type: "line-3d",
  symbolLayers: [
    {
      type: "path",
      profile: "quad", // circle, quad
      material: { color: "red" },
      width: 5,
      height: 5,
    },
  ],
};
```

### PolygonSymbol3D

```javascript
const symbol = {
  type: "polygon-3d",
  symbolLayers: [
    {
      type: "extrude",
      material: { color: "blue" },
      size: 100, // Extrusion height
    },
  ],
};
```

## Visual Variables

Visual variable classes: `ColorVariable`, `SizeVariable`, `OpacityVariable`, `RotationVariable`.

```javascript
import ColorVariable from "@arcgis/core/renderers/visualVariables/ColorVariable.js";
import SizeVariable from "@arcgis/core/renderers/visualVariables/SizeVariable.js";
```

### Size Variable

```javascript
visualVariables: [
  {
    type: "size",
    field: "magnitude",
    stops: [
      { value: 1, size: 4 },
      { value: 5, size: 20 },
      { value: 10, size: 40 },
    ],
  },
];
```

### Color Variable

```javascript
visualVariables: [
  {
    type: "color",
    field: "temperature",
    stops: [
      { value: 0, color: "blue" },
      { value: 50, color: "yellow" },
      { value: 100, color: "red" },
    ],
  },
];
```

### Opacity Variable

```javascript
visualVariables: [
  {
    type: "opacity",
    field: "confidence",
    stops: [
      { value: 0, opacity: 0.1 },
      { value: 100, opacity: 1 },
    ],
  },
];
```

### Rotation Variable

```javascript
visualVariables: [
  {
    type: "rotation",
    field: "heading",
    rotationType: "geographic", // or "arithmetic"
  },
];
```

## Labeling

```javascript
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

```javascript
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.

```javascript
// 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`:

```typescript
layer.renderer = {
  type: "simple",
  symbol: {
    type: "simple-marker",
    color: "red",
    size: 8,
  },
} as const;
```

When you need instance methods, use explicit classes:

```javascript
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 visualization
- `visualization-classbreaks` - ClassBreaksRenderer for numeric data
- `visualization-unique-value-groups` - Grouped unique value renderers
- `visualization-vv-color` - Visual variables with color
- `visualization-pie-chart` - PieChartRenderer for multivariate data
- `visualization-heatmap` - Heatmap visualization
- `visualization-dot-density` - Dot density maps
- `visualization-point-styles` - Point symbol styles
- `labels-basic` - Basic label configuration
- `labels-multiline` - Multiline labels
- `labels-multiple-classes` - Multiple label classes

## Common Pitfalls

1. **Missing type property**: Both renderers and symbols require a `type` property for autocasting.

   ```javascript
   // Anti-pattern: missing type on renderer and symbol
   layer.renderer = {
     symbol: { color: "red", size: 8 },
   };
   ```

   ```javascript
   // 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.

2. **Color formats**: Colors can be hex, named, RGB array, or RGBA array.

   ```javascript
   color: "red";
   color: "#FF0000";
   color: [255, 0, 0];
   color: [255, 0, 0, 0.5]; // With transparency
   ```

3. **Visual variables require numeric fields**: Using a string field for size or color produces no variation.

   ```javascript
   // 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 },
       ],
     },
   ];
   ```

   ```javascript
   // Correct: numeric field for size
   visualVariables: [
     {
       type: "size",
       field: "population", // Numeric field
       stops: [
         { value: 10000, size: 4 },
         { value: 1000000, size: 40 },
       ],
     },
   ];
   ```

4. **Label expressions are Arcade**: Use Arcade syntax (`$feature.fieldName`), not JavaScript.

5. **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 data
- `arcgis-feature-effects` - Visual effects and filters
- `arcgis-core-maps` - Map and view setup
- `arcgis-layers` - Layer types and configuration

More Accessibility skills

← All Accessibility skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY