I have a function
var getMetricValue() { var result = // magic happens here to generate a value based on various factors return result; }
and a simple renderer:
var myRenderer = new SimpleRenderer({
symbol: new SimpleMarkerSymbol({
size: 8,
outline: {
width: 0.5,
color: 'black',
style: 'solid'
}
}),
visualVariables: [{
type: 'color',
field: getWellMetric,
stops: [
{value: 0, color: 'red'},
{value: 100, color: 'blue'}
]
}]
});
However, no matter what value I return from my function I get the same red symbol, even if I hard-code the return value to 100. The documentation states that the field for a visualVariables can be a function. If I use the same method for the field in a classBreaksRenderer then it works OK, but I want a continuous value renderer, not a breaks. Am I using this capability wrong, or is there some other issue?
Solved! Go to Solution.
Michael,
Here is a sample for that:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Data-driven continuous color - 4.4</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.4/esri/css/main.css">
<script src="https://js.arcgis.com/4.4/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/renderers/SimpleRenderer",
"esri/symbols/SimpleFillSymbol",
"esri/widgets/Legend",
"dojo/domReady!"
], function(
Map, MapView, FeatureLayer, SimpleRenderer, SimpleFillSymbol, Legend
) {
var defaultSym = new SimpleFillSymbol({
outline: {
color: "lightgray",
width: 0.5
}
});
// limit visualization to southeast U.S. counties
var defExp = ["STATE = 'LA'", "STATE = 'AL'",
"STATE = 'MS'", "STATE = 'TN'", "STATE = 'GA'",
"STATE = 'FL'", "STATE = 'SC'", "STATE = 'NC'"
];
/*****************************************************************
* Set a color visual variable on the renderer. Color visual variables
* create continuous ramps that map low data values to weak or
* neutral colors and high data values to strong/deep colors. Features
* with data values in between the min and max data values are assigned
* a color proportionally between the min and max colors.
*****************************************************************/
function getMetricValue(evt) {
var result = evt.attributes.POP_POVERTY / 2;
return result;
}
var renderer = new SimpleRenderer({
symbol: defaultSym,
label: "% population in poverty by county",
visualVariables: [{
type: "color",
field: getMetricValue,
normalizationField: "TOTPOP_CY",
stops: [
{
value: 0.1,
color: "#FFFCD4",
label: "<10%"
},
{
value: 0.3,
color: "#350242",
label: ">30%"
}]
}]
});
var povLyr = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/counties_politics_poverty/FeatureS...",
renderer: renderer,
outFields: ["*"],
popupTemplate: {
title: "{COUNTY}, {STATE}",
content: "{POP_POVERTY} of {TOTPOP_CY} people live below the poverty line.",
fieldInfos: [
{
fieldName: "POP_POVERTY",
format: {
digitSeparator: true,
places: 0
}
}, {
fieldName: "TOTPOP_CY",
format: {
digitSeparator: true,
places: 0
}
}]
},
definitionExpression: defExp.join(" OR ") // only display counties from states in defExp
});
var map = new Map({
basemap: "gray",
layers: [povLyr]
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [-85.050200, 33.125524],
zoom: 6
});
/******************************************************************
*
* Add layers to layerInfos on the legend
*
******************************************************************/
var legend = new Legend({
view: view,
layerInfos: [
{
layer: povLyr,
title: "Poverty in the southeast U.S."
}]
});
view.ui.add(legend, "top-right");
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Michael,
I am not seeing in the doc where it says that the field can be a function..?
At Renderer | API Reference | ArcGIS API for JavaScript 4.4 (the description of ColorVisualVariable) the property field lists both String and Function as the data type.
Michael,
OK it helps if you mention you are using the 4.x API. I did not see that tag earlier.
Michael,
Here is a sample for that:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Data-driven continuous color - 4.4</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.4/esri/css/main.css">
<script src="https://js.arcgis.com/4.4/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/renderers/SimpleRenderer",
"esri/symbols/SimpleFillSymbol",
"esri/widgets/Legend",
"dojo/domReady!"
], function(
Map, MapView, FeatureLayer, SimpleRenderer, SimpleFillSymbol, Legend
) {
var defaultSym = new SimpleFillSymbol({
outline: {
color: "lightgray",
width: 0.5
}
});
// limit visualization to southeast U.S. counties
var defExp = ["STATE = 'LA'", "STATE = 'AL'",
"STATE = 'MS'", "STATE = 'TN'", "STATE = 'GA'",
"STATE = 'FL'", "STATE = 'SC'", "STATE = 'NC'"
];
/*****************************************************************
* Set a color visual variable on the renderer. Color visual variables
* create continuous ramps that map low data values to weak or
* neutral colors and high data values to strong/deep colors. Features
* with data values in between the min and max data values are assigned
* a color proportionally between the min and max colors.
*****************************************************************/
function getMetricValue(evt) {
var result = evt.attributes.POP_POVERTY / 2;
return result;
}
var renderer = new SimpleRenderer({
symbol: defaultSym,
label: "% population in poverty by county",
visualVariables: [{
type: "color",
field: getMetricValue,
normalizationField: "TOTPOP_CY",
stops: [
{
value: 0.1,
color: "#FFFCD4",
label: "<10%"
},
{
value: 0.3,
color: "#350242",
label: ">30%"
}]
}]
});
var povLyr = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/counties_politics_poverty/FeatureS...",
renderer: renderer,
outFields: ["*"],
popupTemplate: {
title: "{COUNTY}, {STATE}",
content: "{POP_POVERTY} of {TOTPOP_CY} people live below the poverty line.",
fieldInfos: [
{
fieldName: "POP_POVERTY",
format: {
digitSeparator: true,
places: 0
}
}, {
fieldName: "TOTPOP_CY",
format: {
digitSeparator: true,
places: 0
}
}]
},
definitionExpression: defExp.join(" OR ") // only display counties from states in defExp
});
var map = new Map({
basemap: "gray",
layers: [povLyr]
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [-85.050200, 33.125524],
zoom: 6
});
/******************************************************************
*
* Add layers to layerInfos on the legend
*
******************************************************************/
var legend = new Legend({
view: view,
layerInfos: [
{
layer: povLyr,
title: "Poverty in the southeast U.S."
}]
});
view.ui.add(legend, "top-right");
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Robert,
Thanks for the comprehensive example. I have your code working fine, so now I need to track through and find differences with my implementation. You answered the core question - a function works fine as the field.
Thanks again
Mike