Predominance

Census tracts styled with a unique value renderer, visual variables, and an Arcade expression to show income by educational attainment

What is a predominance style?

A predominance style colors features based on the category with the highest (or predominant) number among a set of similar categories. You can use this style to map anything that involves sub-categories of a larger population.

  1. The winner of an election
  2. The predominant language spoken at home
  3. The most common race/ethnicity in a region

How a predominance style works

This style requires writing an Arcade expression that returns the category with the largest number. The following expression returns a string for the predominant educational attainment level for a given feature.

                                                                                                                                                                           
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />

    <title>
      ArcGIS Developer Guide: Predominance educational attainment
    </title>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.21//esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.21//"></script>

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }
    </style>

    <!--ARCADE SCRIPTS-->

    <script type="text/plain" id="predominance">

      // store field values in variables with
      // meaningful names. Each is the total count
      // of people that attained each education level

      var noHighSchool = $feature.NOHS_CY;
      var someHighSchool = $feature.SOMEHS_CY;
      var highSchool = $feature.HSGRAD_CY;
      var ged = $feature.GED_CY;
      var someCollege = $feature.SMCOLL_CY;
      var associates = $feature.ASSCDEG_CY;
      var bachelors = $feature.BACHDEG_CY;
      var grad = $feature.GRADDEG_CY;

      var all = [
        noHighSchool, someHighSchool, highSchool,
        ged, someCollege, associates,
        bachelors, grad,
      ];

      // Match the maximum value with the label
      // of the respective field and return it for
      // use in a UniqueValueRenderer

      return Decode( Max(all),
        noHighSchool, 'No high school',
        someHighSchool, 'Some high school',
        highSchool, 'High school diploma',
        ged, 'GED',
        someCollege, 'Some college',
        associates, 'Associate\'s degree',
        bachelors, 'Bachelor\'s degree',
        grad, 'Master\'s degree or higher',
      'n/a' );

    </script>

    <script>
      require([
        "esri/config",
        "esri/WebMap",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/widgets/Legend",
        "esri/widgets/Expand"
      ],(esriConfig,WebMap, MapView, FeatureLayer, Legend, Expand)=> {

        esriConfig.apiKey = "YOUR_API_KEY";

        function createSymbol(color) {
          return {
            type: "simple-fill",
            color: color,
            outline: {
              width: 0.3,
              color: [255, 255, 255, 0.2]
            }
          };
        }


        const colors = [ "#00b6f1", "#d9bf0d", "#6a28c7", "#c44245", "#b9a087", "#ab579d", "#78aea0", "#1e8553" ];
        const predominanceArcade = document.getElementById("predominance").text;
        const renderer = {
          type: "unique-value",
          valueExpression: predominanceArcade,
          valueExpressionTitle: "Predominant educational attainment",
          uniqueValueInfos: [
            {
              value: "Master's degree or higher",
              symbol: createSymbol(colors[0])
            }, {
              value: "Bachelor's degree",
              symbol: createSymbol(colors[1])
            }, {
              value: "Associate's degree",
              symbol: createSymbol(colors[2])
            }, {
              value: "Some college",
              symbol: createSymbol(colors[3])
            }, {
              value: "GED",
              symbol: createSymbol(colors[4])
            }, {
              value: "High school diploma",
              symbol: createSymbol(colors[5])
            }, {
              value: "Some high school",
              symbol: createSymbol(colors[6])
            }, {
              value: "No high school",
              symbol: createSymbol(colors[7])
            }
          ]
        };


        const layer = new FeatureLayer({
          portalItem: {
            id: "1cbb0faa0f1f424bbe213bfae9319309"
          },
          renderer: renderer,
          blendMode: "multiply"
        });

        const map = new WebMap({
          portalItem: {
            id: "9cf503b654144873a8e33f996f91ba1d"
          },
          layers: [ layer ]
        });

        const view = new MapView({
          container: "viewDiv",
          map: map,
          scale: 577790,
          center: [ -117.8099, 34.0441 ],
          constraints: {
            snapToZoom:false
          }
        });

        view.ui.add(new Expand({
          content: new Legend({
            view: view
          }),
          view: view,
          expanded: false
        }), "top-right");

      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>

Once the expression is authored, create a unique value renderer and set the following:

  1. Reference the Arcade expression in the valueExpression property.
  2. Create unique value info objects for each of the expected values returned from the expression.

Examples

Predominant value

The following example colors each census tract based on the predominant educational attainment of adults age 25 years or older.

ArcGIS JS API
                                                                                                                                                                           
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />

    <title>
      ArcGIS Developer Guide: Predominance educational attainment
    </title>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.21//esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.21//"></script>

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
    </style>

    <!--ARCADE SCRIPTS-->

    <script type="text/plain" id="predominance">
      // store field values in variables with
      // meaningful names. Each is the total count
      // of people that attained each education level
      var noHighSchool = $feature.NOHS_CY;
      var someHighSchool = $feature.SOMEHS_CY;
      var highSchool = $feature.HSGRAD_CY;
      var ged = $feature.GED_CY;
      var someCollege = $feature.SMCOLL_CY;
      var associates = $feature.ASSCDEG_CY;
      var bachelors = $feature.BACHDEG_CY;
      var grad = $feature.GRADDEG_CY;
      var all = [
      // Match the maximum value with the label
      // of the respective field and return it for
      // use in a UniqueValueRenderer
      return Decode( Max(all),
        noHighSchool, 'No high school',
        someHighSchool, 'Some high school',
        highSchool, 'High school diploma',
        ged, 'GED',
        someCollege, 'Some college',
        associates, 'Associate\'s degree',
        bachelors, 'Bachelor\'s degree',
        grad, 'Master\'s degree or higher',
      'n/a' );
    </script>

    <script>
      require([
        "esri/config",
        "esri/WebMap",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/widgets/Legend",
        "esri/widgets/Expand"
      ],(esriConfig,WebMap, MapView, FeatureLayer, Legend, Expand)=> {
        esriConfig.apiKey = "YOUR_API_KEY";
        function createSymbol(color) {
          return {
            type: "simple-fill",
            color: color,
            outline: {
              width: 0.3,
              color: [255, 255, 255, 0.2]
        const colors = [ "#00b6f1", "#d9bf0d", "#6a28c7", "#c44245", "#b9a087", "#ab579d", "#78aea0", "#1e8553" ];
        const predominanceArcade = document.getElementById("predominance").text;
        const renderer = {
          type: "unique-value",
          valueExpression: predominanceArcade,
          valueExpressionTitle: "Predominant educational attainment",
          uniqueValueInfos: [
            {
              value: "Master's degree or higher",
              symbol: createSymbol(colors[0])
            }, {
              value: "Bachelor's degree",
              symbol: createSymbol(colors[1])
            }, {
              value: "Associate's degree",
              symbol: createSymbol(colors[2])
            }, {
              value: "Some college",
              symbol: createSymbol(colors[3])
            }, {
              value: "GED",
              symbol: createSymbol(colors[4])
            }, {
              value: "High school diploma",
              symbol: createSymbol(colors[5])
            }, {
              value: "Some high school",
              symbol: createSymbol(colors[6])
            }, {
              value: "No high school",
              symbol: createSymbol(colors[7])
            }
          ]
        };
        const layer = new FeatureLayer({
          portalItem: {
            id: "1cbb0faa0f1f424bbe213bfae9319309"
          renderer: renderer,
          blendMode: "multiply"
        const map = new WebMap({
          portalItem: {
            id: "9cf503b654144873a8e33f996f91ba1d"
          layers: [ layer ]
        const view = new MapView({
          container: "viewDiv",
          map: map,
          scale: 577790,
          center: [ -117.8099, 34.0441 ],
          constraints: {
            snapToZoom:false
        view.ui.add(new Expand({
          content: new Legend({
            view: view
          view: view,
          expanded: false
        }), "top-right");
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>

Predominance with opacity

In a predominance visualization, the color representing the predominant value will shade the whole polygon with the same opacity and saturation as any neighboring polygon even if the predominant value wins over other values by the slimmest margin.

Adding an opacity variable helps emphasize strong predominant values and wash out features where the predominant value is relatively weak. The Arcade expression can return the margin between the predominant value and the second place value, or it can be simpler and return the share of the predominant value as a percentage of all values.

ArcGIS JS API
                                                                                                                                                                                               
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />

    <title>
      ArcGIS Developer Guide: Predominance with opacity
    </title>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.21//esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.21//"></script>

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
    </style>

    <!--ARCADE SCRIPTS-->

    <script type="text/plain" id="predominance">
      // store field values in variables with
      // meaningful names. Each is the total count
      // of people that attained each education level
      var noHighSchool = $feature.NOHS_CY;
      var someHighSchool = $feature.SOMEHS_CY;
      var highSchool = $feature.HSGRAD_CY;
      var ged = $feature.GED_CY;
      var someCollege = $feature.SMCOLL_CY;
      var associates = $feature.ASSCDEG_CY;
      var bachelors = $feature.BACHDEG_CY;
      var grad = $feature.GRADDEG_CY;
      var all = [
      // Match the maximum value with the label
      // of the respective field and return it for
      // use in a UniqueValueRenderer
      return Decode( Max(all),
        noHighSchool, 'No high school',
        someHighSchool, 'Some high school',
        highSchool, 'High school diploma',
        ged, 'GED',
        someCollege, 'Some college',
        associates, 'Associate\'s degree',
        bachelors, 'Bachelor\'s degree',
        grad, 'Master\'s degree or higher',
      'n/a' );
    </script>

    <script>
      require([
        "esri/config",
        "esri/WebMap",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/widgets/Legend",
        "esri/widgets/Expand"
      ],(esriConfig,WebMap, MapView, FeatureLayer, Legend, Expand)=> {
        esriConfig.apiKey = "YOUR_API_KEY";
        function createSymbol(color) {
          return {
            type: "simple-fill",
            color: color,
            outline: {
              width: 0.3,
              color: [255, 255, 255, 0.2]
        const colors = [ "#00b6f1", "#d9bf0d", "#6a28c7", "#c44245", "#b9a087", "#ab579d", "#78aea0", "#1e8553" ];
        const predominanceArcade = document.getElementById("predominance").text;
        const renderer = {
          type: "unique-value",
          valueExpression: predominanceArcade,
          valueExpressionTitle: "Predominant educational attainment",
          uniqueValueInfos: [
              value: "Master's degree or higher",
              symbol: createSymbol(colors[0])
              value: "Bachelor's degree",
              symbol: createSymbol(colors[1])
              value: "Associate's degree",
              symbol: createSymbol(colors[2])
              value: "Some college",
              symbol: createSymbol(colors[3])
              value: "GED",
              symbol: createSymbol(colors[4])
              value: "High school diploma",
              symbol: createSymbol(colors[5])
              value: "Some high school",
              symbol: createSymbol(colors[6])
              value: "No high school",
              symbol: createSymbol(colors[7])
        renderer.visualVariables = [{
          type: "opacity",
          valueExpression: `
            var all = [
              $feature.NOHS_CY, $feature.SOMEHS_CY, $feature.HSGRAD_CY,
              $feature.GED_CY, $feature.SMCOLL_CY, $feature.ASSCDEG_CY,
              $feature.BACHDEG_CY, $feature.GRADDEG_CY
            ];
            var predominantValue = Max(all);
            var total = Sum(all);

            return (predominantValue / total) * 100;
          `,
          valueExpressionTitle: "% of people comprising the dominant educational attainment group",
          stops: [
            { value: 22, opacity: 0.05, label: "< 22%" },
            { value: 40, opacity: 1.0, label: "> 40%" }
          ]
        }];
        const layer = new FeatureLayer({
          portalItem: {
            id: "1cbb0faa0f1f424bbe213bfae9319309"
          renderer: renderer,
          blendMode: "multiply"
        const map = new WebMap({
          portalItem: {
            id: "9cf503b654144873a8e33f996f91ba1d"
          layers: [ layer ]
        const view = new MapView({
          container: "viewDiv",
          map: map,
          scale: 577790,
          center: [ -117.8099, 34.0441 ],
          constraints: {
            snapToZoom:false
        view.ui.add(new Expand({
          content: new Legend({
            view: view
          view: view,
          expanded: false
        }), "top-right");
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>

Predominance with size

Many times in demographic maps, large features represent areas with fewer people. In a predominance visualization, the colors of these large features can dominate the view, thus making them appear more influential or important than they actually are.

Adding a size variable that returns the sum of all categories considered in the predominance expression can help provide additional context to the user. This requires switching from a fill symbol to a marker symbol.

This is particularly important for election maps where relatively unimportant large areas dominate the view more than high population areas.

ArcGIS JS API
                                                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />

    <title>
      ArcGIS Developer Guide: Predominance with size
    </title>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.21//esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.21//"></script>

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
    </style>

    <!--ARCADE SCRIPTS-->

    <script type="text/plain" id="predominance">
      // store field values in variables with
      // meaningful names. Each is the total count
      // of people that attained each education level
      var noHighSchool = $feature.NOHS_CY;
      var someHighSchool = $feature.SOMEHS_CY;
      var highSchool = $feature.HSGRAD_CY;
      var ged = $feature.GED_CY;
      var someCollege = $feature.SMCOLL_CY;
      var associates = $feature.ASSCDEG_CY;
      var bachelors = $feature.BACHDEG_CY;
      var grad = $feature.GRADDEG_CY;
      var all = [
      // Match the maximum value with the label
      // of the respective field and return it for
      // use in a UniqueValueRenderer
      return Decode( Max(all),
        noHighSchool, 'No high school',
        someHighSchool, 'Some high school',
        highSchool, 'High school diploma',
        ged, 'GED',
        someCollege, 'Some college',
        associates, 'Associate\'s degree',
        bachelors, 'Bachelor\'s degree',
        grad, 'Master\'s degree or higher',
      'n/a' );
    </script>

    <script>
      require([
        "esri/config",
        "esri/WebMap",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/widgets/Legend",
        "esri/widgets/Expand"
      ],(esriConfig,WebMap, MapView, FeatureLayer, Legend, Expand)=> {
        esriConfig.apiKey = "YOUR_API_KEY";
        function createSymbol(color) {
          return {
            type: "simple-marker",
            color: color,
            outline: {
              width: 0.3,
              color: [0, 0, 0, 0.2]
        const colors = [ "#00b6f1", "#d9bf0d", "#6a28c7", "#c44245", "#b9a087", "#ab579d", "#78aea0", "#1e8553" ];
        const predominanceArcade = document.getElementById("predominance").text;
        const renderer = {
          type: "unique-value",
          valueExpression: predominanceArcade,
          valueExpressionTitle: "Predominant educational attainment",
          uniqueValueInfos: [
              value: "Master's degree or higher",
              symbol: createSymbol(colors[0])
              value: "Bachelor's degree",
              symbol: createSymbol(colors[1])
              value: "Associate's degree",
              symbol: createSymbol(colors[2])
              value: "Some college",
              symbol: createSymbol(colors[3])
              value: "GED",
              symbol: createSymbol(colors[4])
              value: "High school diploma",
              symbol: createSymbol(colors[5])
              value: "Some high school",
              symbol: createSymbol(colors[6])
              value: "No high school",
              symbol: createSymbol(colors[7])
        renderer.visualVariables = [{
          type: "size",
          valueExpression: `
            var all = [
              $feature.NOHS_CY, $feature.SOMEHS_CY, $feature.HSGRAD_CY,
              $feature.GED_CY, $feature.SMCOLL_CY, $feature.ASSCDEG_CY,
              $feature.BACHDEG_CY, $feature.GRADDEG_CY
            ];
            var total = Sum(all);
            return total;
          `,
          valueExpressionTitle: "Population 25+",
          minSize: "2px",
          maxSize: "48px",
          minDataValue: 1000,
          maxDataValue: 15000
        }];
        const layer = new FeatureLayer({
          portalItem: {
            id: "1cbb0faa0f1f424bbe213bfae9319309"
          renderer: renderer,
          blendMode: "multiply"
        const map = new WebMap({
          portalItem: {
            id: "9cf503b654144873a8e33f996f91ba1d"
          layers: [ layer ]
        const view = new MapView({
          container: "viewDiv",
          map: map,
          scale: 288895,
          center: [ -117.8099, 34.0441 ],
          constraints: {
            snapToZoom:false
        view.ui.add(new Expand({
          content: new Legend({
            view: view
          view: view,
          expanded: false
        }), "top-right");
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>

Tutorials

Services

Feature service

Add, update, delete, and query feature data.

API support

Different APIs have different levels of support for data-driven visualization.

Full supportPartial supportNo support

    Tools

    Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.