6

I'm using ArcGIS 10.1 API for JavaScript. I'm showing dynamic map service layer containing 8 layers and I want to show legend for the currently visible layer (only 1 layer is visible at a time). The legend looks ok, but there's one little problem. The legend contains info even for the world map, which is under my visible layer, but I don't want to show this info about world map.

Code snippet:

var legendDijit = new esri.dijit.Legend({
        map:map,
    id: "fluLegend"
}, tsLegDiv);

How can I achieve to ommit info for world map in the legend ?

I haven't found any answer in the other topics containing questions about legend.

Thanks g

The code after Darksanta answer looks like this: The problem is, that the legend loads correctly the first time when layers are added to map, but when I change the layer visibility by changing the 'Year' filter (each layer is visible only when certain year is selected), the legend is as it was and does not reflect the new visible layer. I know, that the Darksanta example (by ArcGIS) is ok, but there must be something fishy in my code, that causes the legend to not work correctly. Maybe the code is completely incorrect. I'm not familiar with js or arcgis, it's my first js + arcgis experience.

<script language="Javascript">
    dojo.require("dijit.layout.BorderContainer");
    dojo.require("dijit.layout.ContentPane");
    dojo.require("dijit.layout.AccordionContainer");
    dojo.require("esri.map");
    dojo.require("esri.dijit.TimeSlider");
    dojo.require("esri.tasks.query");
    dojo.require("esri.layers.FeatureLayer");
    dojo.require("esri.dijit.Legend");

    var map;
    var fluLayers, featureLayer;
    var timeExtent;
    var timeSlider;
    var queryTask, query;//, featureSet;
    var infoTemplate;

    //konstanty
    var defaultLayerIndex = 7;
    var defaultYear = 2006;
    var defaultAgeStart = 6;
    var defaultRangeAge = 8;

    function init() {
        map = new esri.Map("map", {
        basemap: "streets",
        center: [19.63, 48.60],
        zoom: 8
        });

        fluLayers = new esri.layers.ArcGISDynamicMapServiceLayer("<map service address not accessible from outside>");
        fluLayers.setMinScale(0);
        fluLayers.maxRecordCount = 100;
        fluLayers.setOpacity(0.5);

        fluLayers.setVisibleLayers([defaultLayerIndex]);
        setLayerDefinitions(defaultAgeStart, defaultRangeAge);
        map.addLayers([fluLayers]);

        dojo.connect(map, "onLayersAddResult", updateSlider);
        dojo.connect(map,'onLayersAddResult',function(results){
                    var layerInfo = dojo.map(results, function(layer,index){
                                return {layer:layer.layer,title:layer.layer.name};
                    });
                    if(layerInfo.length > 0){
                                var legendDijit = new esri.dijit.Legend({
                                            map:map,
                                            layerInfos:layerInfo
                                },"legendDiv");
                                legendDijit.startup();
                    }
        });
    }

    //Funkcia, ktora nastavi definiciu aktualne viditelnej vrstvy.
    function setLayerDefinitions(ageStart, ageRange){
        var layerDefinitions = [];
        var layerDefString;
        var visibleLayerIndex = getVisibleLayerIndexByYear();

        var startDate = getStartDateByYear();
        var endDate = getEndDateByYear();

        if (ageRange === 0)
            layerDefString = "Chripka.STARTAGE = " + ageStart + " AND Chripka.RANGEAGE IS NULL AND Chripka.PERIODSTART >= date \'" + startDate + "\' AND Chripka.PERIODSTART < date \'" + endDate + "\'";
        else
            layerDefString = "Chripka.STARTAGE = " + ageStart + " AND Chripka.RANGEAGE = " + ageRange + " AND Chripka.PERIODSTART >= date \'" + startDate + "\' AND Chripka.PERIODSTART < date \'" + endDate + "\'";

        layerDefinitions[visibleLayerIndex] = layerDefString;
        fluLayers.setLayerDefinitions(layerDefinitions);
    }

    //Funkcia, ktora aktualizuje timeSlider v pripade nejakej zmeny.
    function updateSlider() {
        if (dijit.byId('timeSlider')) {
            dijit.byId('timeSlider').destroy();
        }

        var tsDiv = dojo.create("div", null, dojo.byId('timeSliderDiv'));

        timeSlider = new esri.dijit.TimeSlider({
            style: "width: 1000px;",
            id: 'timeSlider'
        }, tsDiv);

        map.setTimeSlider(timeSlider);
        timeSlider.setThumbCount(2);

        if (!timeExtent)
            setTimeExtentByYear();
        timeSlider.createTimeStopsByTimeInterval(timeExtent, 1, 'esriTimeUnitsWeeks');
        timeSlider.setThumbIndexes([0, 1]);
        timeSlider.setThumbMovingRate(4000);
        timeSlider.startup();
        dojo.byId("daterange").innerHTML = "<i>" + timeSlider.timeStops[0].toLocaleDateString() + " - " + timeSlider.timeStops[1].toLocaleDateString() + "<\/i>";

        //add labels for every other time stop
        var labels = dojo.map(timeSlider.timeStops, function(timeStop, i) { 
            if ( i % 2 === 0 ) {
                return i + 1;
            } else {
                return "";
            }
        });

        timeSlider.setLabels(labels);

        dojo.connect(timeSlider, "onTimeExtentChange", function(timeExtent) {
            var startValString = timeExtent.startTime.toLocaleDateString();
            var endValString = timeExtent.endTime.toLocaleDateString();

            dojo.byId("daterange").innerHTML = "<i>" + startValString + " - " + endValString + "<\/i>";
        });
    }

    function getStartDateBySlider(){
        var startDate;

        if (timeSlider){
            if (timeSlider.getCurrentTimeExtent()){
                var tex = timeSlider.getCurrentTimeExtent().startTime;
                startDate = (tex.getUTCMonth() + 1).toString() + "/" + tex.getUTCDate().toString() + "/" + tex.getUTCFullYear().toString();
            }
        }

        if (!startDate)
            startDate = getStartDateByYearExt("2006");

        return startDate;
    }

    function getEndDateBySlider(){
        var endDate;

        if (timeSlider){
            if (timeSlider.getCurrentTimeExtent()){
                var tex = timeSlider.getCurrentTimeExtent().endTime;
                endDate = (tex.getUTCMonth() + 1).toString() + "/" + tex.getUTCDate().toString() + "/" + tex.getUTCFullYear().toString();
            }
        }

        if (!endDate)
            endDate = getEndDateByYearExt("2006");

        return endDate;
    }

    //Funkcia, ktora je vykonana potom, ako dojde ku zmene roku.
    function yearChange() {
        //if the slider is currently playing stop and reset it
        if (timeSlider.playing) {
            timeSlider.pause();
        }

        setTimeExtentByYear();

        var ageStart = getSelectedStartAge();
        var rangeAge = getSelectedRangeAge();
        onUpdateLayerDefinitions(ageStart, rangeAge);
    }

    //Funkcia, ktora nastavi timeExtent podla zvoleneho roku.
    function setTimeExtentByYear(){
        var year = dojo.byId('year').value;

        var startDate, endDate;
        startDate = getStartDateByYearExt(year);
        endDate = getEndDateByYearExt(year);

        timeExtent = new esri.TimeExtent();
        timeExtent.startTime = new Date(startDate + " UTC");
        timeExtent.endTime = new Date(endDate + " UTC");

        dojo.byId("timeSliderYear").innerHTML = year;
        dojo.byId("daterangeYear").innerHTML = "<strong>" + timeExtent.startTime.toLocaleDateString() + " - " + timeExtent.endTime.toLocaleDateString() + "<\/strong>";
        dojo.byId("ageRange").innerHTML = getSelectedAgeRangeString();
    }

    //Funkcia, ktora vrati zaciatocny datum pre zvoleny rok.
    function getStartDateByYear(){
        var year = dojo.byId('year').value;
        return getStartDateByYearExt(year);
    }

    //Funkcia, ktora vrati koncovy datum pre zvoleny rok.
    function getEndDateByYear(){
        var year = dojo.byId('year').value;
        return getEndDateByYearExt(year);
    }

    //Funkcia, ktora vrati zaciatocny datum pre zvoleny rok, ktory pride ako stringovy parameter.
    function getStartDateByYearExt(year){
        return "09/29/2006"; //SIMPLE
    }

    //Funkcia, ktora vrati koncovy datum pre zvoleny rok, ktory pride ako stringovy parameter.
    function getEndDateByYearExt(year){
        return "12/29/2006"; //SIMPLE
    }

    //Funkcia, ktora vrati zvoleny zaciatocny vek.
    function getSelectedStartAge(){
        return defaultAgeStart; //SIMPLE
    }

    //Funkcia, ktora vrati ku zvolenemu zaciatocnemu veku jeho rozsah.
    function getSelectedRangeAge(){
        return defaultRangeAge; //SIMPLE
    }

    //Funkcia, ktora vrati zvoleny vekovy rozsah ako retazec.
    function getSelectedAgeRangeString(){
        var radios = dojo.query(".list_item");

        for (var i=0, il = radios.length; i < il; i++) {
            if (radios[i].checked) {
                return radios[i].value;
            }
        }

        return "";
    }

    //Funkcia, ktora aktualizuje definiciu aktualne viditelnej vrstvy a spravi vsetko ostatne spojene s touto aktualizaciou vrstvy.
    function onUpdateLayerDefinitions(ageStart, ageRange){
        //default je vekove rozpatie 6-8
        if (typeof ageStart === 'undefined')
            ageStart = defaultAgeStart;

        if (typeof ageRange === 'undefined')
            ageRange = defaultRangeAge;

        var visibleLayerIndex = getVisibleLayerIndexByYear();
        fluLayers.setVisibleLayers([visibleLayerIndex]);

        setLayerDefinitions(ageStart, ageRange);

        updateSlider();
    }

    //Funkcia, ktora vrati index viditelnej vrstvy, tzn. zavisi to od zvoleneho roku.
    function getVisibleLayerIndexByYear(){
            return 6; //SIMPLE
        }
    }

    //Funkcia, ktora je vykonana potom, ako dojde ku zmene filtracneho kriteria.
    function filterChange() {
        //if the slider is currently playing stop and reset it
        if (timeSlider.playing) {
            timeSlider.pause();
        }

        setTimeExtentByYear();

        var ageStart = getSelectedStartAge();
        var rangeAge = getSelectedRangeAge();
        onUpdateLayerDefinitions(ageStart, rangeAge);
    }

    dojo.ready(init);

</script>
5
  • Hi, how the legends are dependent to show? Each of the features, or each of the layer's full extent? In the former case, I guess you need to query feature which are in the visible extent for every time you refresh view.
    – Darksanta
    Apr 17, 2013 at 9:42
  • As I wrote earlier, the legend looks ok. When I change the layer visibility, the legend changes too. The legend contains every info about the visible layer (it's just colors and numbers, which explain, what do the colors mean), which is what I want (the extent is not important). I just want to remove the world map legend info part from my legend, because the world map legend is either map type dependent (the legend changes, when I use "topo" or "streets" map type) and either not very usefull for my example, that I'm working on. I just don't know, how to remove this world map legend part.
    – ghostC
    Apr 17, 2013 at 12:37
  • I wrote answer and hope this must be what you want. Please note that World Map says Basemap in ArcGIS.
    – Darksanta
    Apr 17, 2013 at 13:30
  • I've added the whole code sample into my question. Maybe there are bugs that cause that the code is not working as it should.
    – ghostC
    Apr 18, 2013 at 7:52
  • Please check my answer edited part. Conclusion, you are adding MapService instead of FeatureService, so you need to refresh Legend with hideLayers parameter.
    – Darksanta
    Apr 19, 2013 at 4:20

2 Answers 2

5

To omit Legend, you have to set Legend::LayerInfos parameter which LayerInfo you want to show. As bellow,

//add the legend
dojo.connect(map,'onLayersAddResult',function(results){
  var layerInfo = dojo.map(results, function(layer,index){
    return {layer:layer.layer,title:layer.layer.name};
  });
  if(layerInfo.length > 0){
    var legendDijit = new esri.dijit.Legend({
      map:map,
      layerInfos:layerInfo
    },"legendDiv");
    legendDijit.startup();
  }
});

map.addLayers([waterbodies,rivers]);

This code is from ESRI's sample. http://help.arcgis.com/en/webapi/javascript/arcgis/jssamples/widget_legend.html

This sample shows only two layers and do not show basemap Layer.

EDITED:
If you are adding DynamicMapServeLayer instead of FeatureLayer and want to control each Layers visibility inside of the MapService, you need to refresh LayerInfo with hideLayers parameter.

//show only index of 0 Layer
//layer is ArcGISDynamicMapServiceLayer object
layer.setVisibleLayers([0]);
// get legend dijit
var legendDijit = dijit.byId("legendDiv");

var visibleLayers = layer.visibleLayers;
var layerInfos = layer.layerInfos;

//create hideLayers array from layerInfos which layers are not visible
var hideLayers = [];
for (var i = 0; i < layerInfos.length; i ++) {

    var layerInfo = layerInfos[i];
    if(visibleLayers.indexOf(layerInfo.id) == -1){

        hideLayers.push(layerInfo.id)
    }
}

//refresh legend dijit with hideLayers
legendDijit.refresh([{layer:layer, hideLayers:hideLayers}]);
0
0

This is the final code:

        function init() {
            //some code here

            dojo.connect(map, "onLayersAddResult", updateSlider);
            dojo.connect(map, "onLayersAddResult", initLegend);
        }

        //Inicializacia legendy po starte.
        function initLegend(results){
            var layerInfo = dojo.map(results, function(layer, index){
                return {layer:layer.layer, title:layer.layer.name};
            });

            if(layerInfo.length > 0){
                legendDijit = new esri.dijit.Legend({
                    map:map,
                    layerInfos:layerInfo
                },"legendDiv");

                legendDijit.startup();
            }
        }

        //Aktualizacia legendy, ak dojde ku nejakej zmene vo vrstvach (viditelnost vrstiev).
        function updateLegend(){
            var visibleLayers = fluLayers.visibleLayers;
            var layerInfos = fluLayers.layerInfos;

            //create hideLayers array from layerInfos which layers are not visible
            var hideLayers = [];

            for (var i = 0; i < layerInfos.length; i ++) {
                var layerInfo = layerInfos[i];

                if(visibleLayers.indexOf(layerInfo.id) == -1){
                    hideLayers.push(layerInfo.id)
                }
            }

            //refresh legend dijit with hideLayers
            legendDijit.refresh([{layer:fluLayers, hideLayers:hideLayers}]);
        }

        function filterChange() {
            //some code here...

            updateLegend();
        }

In the Init function is the creation of the legend dijit (initLegend) and when I change the visible layers, the function updateLegend updates the legend according to the visible layer. Thanks goes to Darksanta.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.