Wurman dots

Explore in the sandboxView live

This sample reveals a visualization style, Wurman Dots, which represents values through various fill amounts within gridded circles. The style was inspired by the 1966 book Urban Atlas: 20 American Cities by Richard Saul Wurman. In it, the maps’ style lends itself to single topics, such as population density, and also multiple topics, such as population density and income. The statistical data is represented as inner circles proportional to the data inside a grid of equally-sized outer circles. Higher percentages are represented by symbols that are more filled-in whereas lower percentages show circles that are more empty. Areas with no value at all are not symbolized.


In this sample, we fill the circles based on the percentage of land covered by forest (NLCD). We use a color visual variable to represent total population. Heavily forested areas are represented by circles that are filled in. High population areas are orange, and areas with little or no population are green.

We achieve this visualization using a CIMSymbol in a SimpleRenderer. CIM symbols are used to display multi-layer vector symbols for features and graphics in MapView.

The CIMSymbol has two symbol layers - one representing the outer circle (total area), the other represents the inner circle (or percent of forested area). The outer circle varies its size by view scale. The inner circle varies its size by view scale multiplied by the percentage of forested land.

The snippet below demonstrates how to override the inner circle's size with an Arcade expression.

symbol.primitiveOverrides = [
    type: "CIMPrimitiveOverride",
    primitiveName: "innerSizeOverride",
    propertyName: "Size",
    valueExpressionInfo: {
      type: "CIMExpressionInfo",
      title: "Size in pixels of inner ring at maxScale",
      // outerSize is the pixel size at the largest scale
      // The innerSize is determined by multiplying
      // the outerSize by the forest ratio
      expression: `
        const outerSize = 42 * 2311161 / $view.scale;
        const forestRatio = $feature.NLCDfrstPt / 100;
        const innerSize = outerSize * forestRatio;
        return IIF( innerSize < 3, 3, innerSize );
      returnType: "Default"

See the CIM specification for more information.