Unique Value Renderer and the TOC

1699
4
Jump to solution
09-23-2014 03:16 PM
DavidColey
Frequent Contributor

Hi all-

So I'm trying to render groups of values based on the blog at:

Data Visualization with ArcGIS API for JavaScript: Show Data by Unique Value | ArcGIS Blog

The problem is that while the renderer portion works great, I can't seem to get around the fact that the TOC wants to list the "if else if" statement text within Nianwei Liu's table of contents.  Here is some code of what I've done so far, I just can't seem to around the fact that the TOC wants to list the attribute field values on which I am rendering, but is listing the function text instead:

var defSym = new SimpleFillSymbol().setStyle(SimpleFillSymbol.STYLE_SOLID);

  defSym.outline.setStyle(SimpleLineSymbol.STYLE_SOLID);

var cszRenderer = new UniqueValueRenderer(defSym, function(graphic) {

if (graphic.attributes['CODE'].indexOf("DTB") !== -1 || graphic.attributes['CODE'].indexOf("DTC") !== -1 ||

          graphic.attributes['CODE'].indexOf("DTE") !== -1 || graphic.attributes['CODE'].indexOf("DTN") !== -1){

          return "Downtown Overlays";

} else if (graphic.attributes['CODE'].indexOf("G") !== -1 || graphic.attributes['CODE'].indexOf("GU") !== -1){

          return "Government Use";

} else {

         return "Other Uses";  

         };

  });

var dtSym = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color("#808000"), 2),new Color("#FF8C00"));

        cszRenderer.addValue("Downtown Overlays", dtSym);

  var gSym = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color("#808080"), 2),new Color("#A4F9FE"));

        cszRenderer.addValue("Government Use", gSym);

lyrCsZoning.setRenderer(cszRenderer);

Result:

tocCapture.PNG

Any help is appreciated.  If I can just somehow reverse how the renderer is set up so I can return the attribute and not the function.  Some sort of nested function I think would work but I just can't see it--

Thanks-

David

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
KenBuja
MVP Esteemed Contributor

I was able to get rid of that text with a small modification to the TOC.js. This is a local copy I have of the current TOC

I commented out line 238

anode.innerHTML = af;

which is part of this larger section

if (r.infos) {

  //UniqueValueRenderer |ClassBreaksRenderer

  var legs = r.infos;

  if (r.defaultSymbol && legs.length > 0 && legs[0].label != '[all other values]') {

    // insert at top

    legs.unshift({

      label: '[all other values]',

      symbol: r.defaultSymbol

    })

  }

  var af = r.attributeField + (r.normalizationField ? '/' + r.normalizationField : '');

  af += (r.attributeField2 ? '/' + r.attributeField2 : '') + (r.attributeField3 ? '/' + r.attributeField3 : '');

  var anode = domConstruct.create('div', {}, this.containerNode);

  domStyle.set(anode, 'paddingLeft', '' + this.rootLayerTOC.tocWidget.indentSize * (this.rootLayerTOC._currentIndent + 2) + 'px');

  //anode.innerHTML = af;

  this._createChildrenNodes(legs, 'legend');

} else {

  //this._createChildrenNodes([rootLayer.renderer], 'legend');

  this._setIconNode(rootLayer.renderer, this.iconNode, this);

  domConstruct.destroy(this.containerNode);

  this.containerNode = null;

}

It turns out that r.attributeField is where the function text is held.

I haven't tested it on other situations (renderers or not), so I don't know what that larger implications of that will be.

I tested it with this code

<!DOCTYPE html>

<html>

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />

    <title>Data Visualization - Unique Value Renderer with Function Conversion</title>

    <link rel="stylesheet" href="https://community.esri.com//js.arcgis.com/3.10/js/esri/css/esri.css">

    <style>

        html, body, #map {

            height: 100%;

            margin: 0;

        }

        #info {

            position: absolute;

            left: 0;

            bottom: 0;

            padding: 10px;

            background-color: #fff;

        }

    </style>

    <script>

        var dojoConfig = {

            parseOnLoad: true,

            packages: [

                {

                    name: "agsjs",

                    location: location.pathname.replace(/\/[^/]+$/, "") + '../../_assets/agsjs'

                    //"location": 'http://gmaps-utility-gis.googlecode.com/svn/tags/agsjs/latest/build/agsjs' // for xdomain load

                }]

        };

    </script>

    <script src="//js.arcgis.com/3.10/"></script>

    <script>

        require([

        "esri/map",

        "esri/layers/FeatureLayer",

        "esri/renderers/UniqueValueRenderer",

        "esri/symbols/SimpleMarkerSymbol",

        "esri/Color",

        "esri/dijit/Legend",

        "agsjs/dijit/TOC",

        "dojo/domReady!"

        ], function (Map, FeatureLayer, UniqueValueRenderer, SimpleMarkerSymbol, Color, Legend, TOC) {

            var map = new Map("map", {

                basemap: "gray",

                center: [-100, 40],

                zoom: 5

            });

            var layer = new FeatureLayer("//services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/NationalParkStats2013/FeatureServer/0", {

                outFields: ["Address"]

            });

            var symbol = new SimpleMarkerSymbol();

            symbol.setColor(new Color("#fffcd4"));

            var renderer = new UniqueValueRenderer(null, function (graphic) {

                if (graphic.attributes['Address'].indexOf("CA") !== -1 || graphic.attributes['Address'].indexOf("OR") !== -1 || graphic.attributes['Address'].indexOf("WA") !== -1) {

                    return "Pacific West";

                } else {

                    return "Other Areas";

                };

            });

            var symbol1 = new SimpleMarkerSymbol();

            symbol1.setColor(new Color("#7b3578"));

            renderer.addValue("Pacific West", symbol1);

            var symbol2 = new SimpleMarkerSymbol();

            symbol2.setColor(new Color("#cccccc"));

            renderer.addValue("Other Areas", symbol2);

            layer.setRenderer(renderer);

            map.addLayers([layer]);

            //var legend = new Legend({

            //    map: map,

            //    layerInfos: [{

            //        layer: layer

            //    }]

            //}, "legend");

            //legend.startup();

            map.on("layers-add-result", function () {

                toc = new TOC({

                    map: map,

                    layerInfos: [{

                        layer: layer,

                        title: "Test"

                    }]

                }, "divTOC");

                toc.startup();

            });

        });

    </script>

</head>

<body>

    <div id="map"></div>

    <div id="info">

        <div id="divTOC"></div>

    </div>

</body>

</html>

View solution in original post

0 Kudos
4 Replies
KenBuja
MVP Esteemed Contributor

I was able to get rid of that text with a small modification to the TOC.js. This is a local copy I have of the current TOC

I commented out line 238

anode.innerHTML = af;

which is part of this larger section

if (r.infos) {

  //UniqueValueRenderer |ClassBreaksRenderer

  var legs = r.infos;

  if (r.defaultSymbol && legs.length > 0 && legs[0].label != '[all other values]') {

    // insert at top

    legs.unshift({

      label: '[all other values]',

      symbol: r.defaultSymbol

    })

  }

  var af = r.attributeField + (r.normalizationField ? '/' + r.normalizationField : '');

  af += (r.attributeField2 ? '/' + r.attributeField2 : '') + (r.attributeField3 ? '/' + r.attributeField3 : '');

  var anode = domConstruct.create('div', {}, this.containerNode);

  domStyle.set(anode, 'paddingLeft', '' + this.rootLayerTOC.tocWidget.indentSize * (this.rootLayerTOC._currentIndent + 2) + 'px');

  //anode.innerHTML = af;

  this._createChildrenNodes(legs, 'legend');

} else {

  //this._createChildrenNodes([rootLayer.renderer], 'legend');

  this._setIconNode(rootLayer.renderer, this.iconNode, this);

  domConstruct.destroy(this.containerNode);

  this.containerNode = null;

}

It turns out that r.attributeField is where the function text is held.

I haven't tested it on other situations (renderers or not), so I don't know what that larger implications of that will be.

I tested it with this code

<!DOCTYPE html>

<html>

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />

    <title>Data Visualization - Unique Value Renderer with Function Conversion</title>

    <link rel="stylesheet" href="https://community.esri.com//js.arcgis.com/3.10/js/esri/css/esri.css">

    <style>

        html, body, #map {

            height: 100%;

            margin: 0;

        }

        #info {

            position: absolute;

            left: 0;

            bottom: 0;

            padding: 10px;

            background-color: #fff;

        }

    </style>

    <script>

        var dojoConfig = {

            parseOnLoad: true,

            packages: [

                {

                    name: "agsjs",

                    location: location.pathname.replace(/\/[^/]+$/, "") + '../../_assets/agsjs'

                    //"location": 'http://gmaps-utility-gis.googlecode.com/svn/tags/agsjs/latest/build/agsjs' // for xdomain load

                }]

        };

    </script>

    <script src="//js.arcgis.com/3.10/"></script>

    <script>

        require([

        "esri/map",

        "esri/layers/FeatureLayer",

        "esri/renderers/UniqueValueRenderer",

        "esri/symbols/SimpleMarkerSymbol",

        "esri/Color",

        "esri/dijit/Legend",

        "agsjs/dijit/TOC",

        "dojo/domReady!"

        ], function (Map, FeatureLayer, UniqueValueRenderer, SimpleMarkerSymbol, Color, Legend, TOC) {

            var map = new Map("map", {

                basemap: "gray",

                center: [-100, 40],

                zoom: 5

            });

            var layer = new FeatureLayer("//services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/NationalParkStats2013/FeatureServer/0", {

                outFields: ["Address"]

            });

            var symbol = new SimpleMarkerSymbol();

            symbol.setColor(new Color("#fffcd4"));

            var renderer = new UniqueValueRenderer(null, function (graphic) {

                if (graphic.attributes['Address'].indexOf("CA") !== -1 || graphic.attributes['Address'].indexOf("OR") !== -1 || graphic.attributes['Address'].indexOf("WA") !== -1) {

                    return "Pacific West";

                } else {

                    return "Other Areas";

                };

            });

            var symbol1 = new SimpleMarkerSymbol();

            symbol1.setColor(new Color("#7b3578"));

            renderer.addValue("Pacific West", symbol1);

            var symbol2 = new SimpleMarkerSymbol();

            symbol2.setColor(new Color("#cccccc"));

            renderer.addValue("Other Areas", symbol2);

            layer.setRenderer(renderer);

            map.addLayers([layer]);

            //var legend = new Legend({

            //    map: map,

            //    layerInfos: [{

            //        layer: layer

            //    }]

            //}, "legend");

            //legend.startup();

            map.on("layers-add-result", function () {

                toc = new TOC({

                    map: map,

                    layerInfos: [{

                        layer: layer,

                        title: "Test"

                    }]

                }, "divTOC");

                toc.startup();

            });

        });

    </script>

</head>

<body>

    <div id="map"></div>

    <div id="info">

        <div id="divTOC"></div>

    </div>

</body>

</html>

0 Kudos
DavidColey
Frequent Contributor

Way to go Ken, that did it.  Clearly I need to spend more time with the TOC widget, but I see it now: this is where Nianwei Liu‌ is placing the attributeField name of the attribute to be listed when rendering unique values.  I would only caution users that by commenting out the attributeField option, no layers in the TOC will displace a header.  Thanks again for your help!

0 Kudos
NianweiLiu
Occasional Contributor II

I put in a string type check for the second parameter of the renderere constructor in the latest check in. That shold take care of the problem.

DavidColey
Frequent Contributor

Thank you Nianwei - I incorporated the changes, works like a charm.  attribubeField is displayed where the UNR is utilitizing a string, and not where the UNR is utilizing a function.  Thank you for your all of your work on this widget over the years - it is quite an elegant solution.  Robert Robert Scheitlin, GISP, thanks to you as well--

David

0 Kudos