agentleFS
GeoDaoyuGeoDaoyu/arcgis-maps-sdk-js-ai-context/skills/arcgis-visualization/SKILL.md

arcgis-visualization

Skill0 starsChanged 7 months agoMITView on GitHub

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.

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 3 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

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

    line 8
  2. Distinctive:

    All symbol and renderer objects support autocasting - use plain objects instead of constructing classes.

    line 537
  3. Distinctive:

    When you need instance methods, use explicit classes:

    line 564
  4. Very specific:

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

    line 659

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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, replace import X from "path" with const X = await $arcgis.import("path").

Renderer Types Overview

RendererAutocast TypeUse 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 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.

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

  2. 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
  3. 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 },
        ],
      },
    ];
  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

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.