Skip to content
Snippets Groups Projects
collections_LayerLegend.js.html 16.8 KiB
Newer Older
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: collections/LayerLegend.js</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: collections/LayerLegend.js</h1>

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>/**
 * Created by gavorhes on 12/16/2015.
 */
Glenn Vorhes's avatar
Glenn Vorhes committed
import $ from '../jquery/jquery';
import provide from '../util/provide';
import makeGuid from '../util/makeGuid';
import mapMove from '../olHelpers/mapMove';
let nm = provide('collections');

class LayerGroup {

    /**
     *
     * @param {object} [groupConfig={}] - group configuration object
     * @param {string} groupConfig.groupName - the group name
     * @param {boolean} [groupConfig.collapse=false] - if the group should be collapsed initially
     * @param {boolean} [groupConfig.addCheck=true] - if the group should have a checkbox controlling visibility of all layers
     * @param {LayerGroup} [parent=undefined] - the parent group
     */
    constructor(groupConfig, parent) {
        this.groupLayers = [];
        this.groupLayersLookup = {};
        this.groupGroups = [];
        this.groupGroupsLookup = {};
        this.itemIdArray = [];

        if (typeof groupConfig == 'undefined') {
            this.parent = null;
            this.groupId = 'root';
            this.groupName = 'root';
            this.allGroupLookup = {root: this};
            this.allGroupArray = [this];
            this.allLayerArray = [];
            this.allLayerLookup = {};
            this.layerParentLookup = {};
            this.collapse = false;
            this.addCheck = false;
        } else {
            this.groupId = makeGuid();
            this.parent = parent;
            this.groupName = groupConfig.groupName;
            this.collapse = typeof  groupConfig.collapse == 'boolean' ? groupConfig.collapse : false;
            this.addCheck = typeof  groupConfig.addCheck == 'boolean' ? groupConfig.addCheck : true;
        }
    }

    /**
     *
     * @param {object} groupConfig - configuration object
     * @param {string} groupConfig.groupName - the group name
     * @param {boolean} groupConfig.collapse if the group should be collapsed initially
     * @param {boolean} groupConfig.addCheck if the group should have a checkbox controlling visibility of all layers
     * @param {Array&lt;LayerGroup>} parents parent groups
     * @returns {LayerGroup} the layer group just added
     */
    addGroup(groupConfig, parents) {
        let parent;
        if (parents.length > 0) {
            parent = parents[parents.length - 1];
        } else {
            parent = 'root';
        }


        /**
         * @type {LayerGroup}
         */
        let parentGroup = this.allGroupLookup[parent];
        let newGroup = new LayerGroup(groupConfig, parentGroup);
        this.allGroupLookup[newGroup.groupId] = newGroup;
        this.allGroupArray.push(newGroup);

        parentGroup.groupGroups.push(newGroup);
        parentGroup.groupGroupsLookup[newGroup.groupId] = newGroup;

        if (parentGroup.itemIdArray.indexOf(newGroup.groupId) > 0) {
            console.log(newGroup.groupId);
            throw 'layer and group ids must be unique';
        }
        parentGroup.itemIdArray.push(newGroup.groupId);

        return newGroup;
    }

    /**
     *
     * @param {LayerBase} newLayer the layer to be added
     * @param {Array} parents array
     */
    addLegendLayer(newLayer, parents) {
        let parent;
        if (parents.length > 0) {
            parent = parents[parents.length - 1];
        } else {
            parent = 'root';
        }

        this.allLayerLookup[newLayer.id] = newLayer;
        this.allLayerArray.push(newLayer);

        /**
         * @type {LayerGroup}
         */
        let parentGroup = this.allGroupLookup[parent];

        parentGroup.groupLayers.push(newLayer);
        parentGroup.groupLayersLookup[newLayer.id] = newLayer;
        if (parentGroup.itemIdArray.indexOf(newLayer.id) > 0) {
            console.log(newLayer.id);
            throw 'layer and group ids must be unique';
        }
        parentGroup.itemIdArray.push(newLayer.id);

        this.layerParentLookup[newLayer.id] = parentGroup;

    }

    getLegendHtml(legendId, options) {


        let legendHtml = `&lt;ul id="${legendId}" class="legend-container">`;

        legendHtml += `&lt;li>${options.legendTitle}&lt;input type="checkbox" checked id="suppress-by-extent-${legendId}" class="suppress-by-extent">` +
            `&lt;label title="Suppress layers not visible at this zoom level" for="suppress-by-extent-${legendId}">` +
            `&lt;span>&lt;/span>` +
            `&lt;/label>&lt;/li>`;

        legendHtml += this._buildLegend(this.itemIdArray, this, options.layerDivClasses) + '&lt;/ul>';

        return legendHtml;
    }

    /**
     * @param {Array} itemIds the items to process
     * @param {LayerGroup} theGroup new group
     * @param {Array} [layerDivClasses=[]] optional classes to apply to the layer divs
     * @static
     * @returns {string} html string
     */
    _buildLegend(itemIds, theGroup, layerDivClasses) {

        if (itemIds.length == 0) {
            return '';
        }

        let theHml = '';

        let itemId = itemIds[0];

        if (theGroup.groupLayersLookup[itemId]) {

            /**
             * @type {LayerBase}
             */
            let lyr = theGroup.groupLayersLookup[itemId];
            theHml += `&lt;li id="${lyr.id}-layer-li" class="legend-layer-li ${layerDivClasses.join(' ')}">` + lyr.getLegendDiv() + '&lt;/li>';


        } else if (theGroup.groupGroupsLookup[itemId]) {
            /**
             * type {LayerGroup}
             */
            let otherGroup = theGroup.groupGroupsLookup[itemId];

            theHml += `&lt;li>`;
            theHml += `&lt;div id="${otherGroup.groupId}-legend-layer-div" ` +
                `class="legend-layer-group  ${layerDivClasses.join(' ')}">`;

            if (otherGroup.addCheck) {
                theHml += `&lt;input type="checkbox" checked id="${otherGroup.groupId}-group-chck">` +
                    `&lt;label for="${otherGroup.groupId}-group-chck" title="Click arrow to expand or collapse">${otherGroup.groupName}&lt;/label>`;
            } else {
                theHml += `&lt;label title="Click arrow to expand or collapse">${otherGroup.groupName}&lt;/label>`;
            }

            theHml += `&lt;span title="Expand/Collapse" class="layer-group-expander`;
            theHml += `${otherGroup.collapse ? ' legend-layer-group-initial-collapse' : ''}">`;
            theHml += otherGroup.collapse ? '&amp;#9654;' : '&amp;#9660;';
            theHml += '&lt;/span>';

            //parents.push(groupId);
            theHml += '&lt;ul>' + this._buildLegend(otherGroup.itemIdArray, otherGroup, layerDivClasses) + '&lt;/ul>';
            theHml += '&lt;/div>';
            theHml += '&lt;/li>';
        }

        return theHml + this._buildLegend(itemIds.slice(1), theGroup, layerDivClasses);
    }
}

/**
 * a wrapper to make a legend
 */
class LayerLegend {

    /**
     *
     * @param {Array} legendItems array of layers or objects with {groupName:  {string}, collapse: {boolean}, addCheck: {boolean}, items: {Array}}
     * @param {string} divId the div where the legend should be added
     * @param {object} options for legend
     * @param {Array} [options.layerDivClasses=[]] optional array of classes to be applied to the layer legend divs for custom styling
     * @param {string} [options.legendTitle=Legend] the legend title
     * @param {bool} [options.scaleDependent=true] if legend display is scale dependent
     */
    constructor(legendItems, divId, options) {
        for (let i of legendItems) {
            if (typeof i == 'undefined') {
                throw 'undefined item passed in array to legend constructor';
            }
        }

        options = options || {};

        options.legendTitle = typeof options.legendTitle == 'string' ? options.legendTitle : 'Legend';
        options.scaleDependent = typeof options.scaleDependent == 'boolean' ? options.scaleDependent : true;
        options.layerDivClasses = options.layerDivClasses || [];

        // if legend display is scale dependent, make sure the mapMove object is initialized first
        if (options.scaleDependent) {
            mapMove.checkInit();
        }

        this.$divElement = $('#' + divId);

        this._legendItems = legendItems;

        this.layerGroup = new LayerGroup();

        this._buildTree(legendItems);

        this.legendId = makeGuid();

        this.$divElement.append(this.layerGroup.getLegendHtml(this.legendId, options));

        for (let l of this.layerGroup.allLayerArray){
            l.applyCollapse();
        }

        let _this = this;

        //// if legend display is scale dependent, make sure the mapMove object is initialized first
        if (options.scaleDependent) {
            mapMove.checkInit();

            mapMove.addCallback(function (ext, zoom, evt) {
                if (typeof evt == 'undefined' || evt == 'change:resolution') {
                    for (let lyr of this.layerGroup.allLayerArray) {
                        let $lyrLi = $('#' + lyr.id + '-layer-li');
                        if (zoom > lyr.maxZoom || zoom &lt; lyr.minZoom) {
                            $lyrLi.addClass('layer-not-visible');
                        } else {
                            $lyrLi.removeClass('layer-not-visible');
                        }
                    }
                }
            }, this, 100, true, 'legend1');
        }

        // &lt;editor-fold desc="add event listeners">

        this.$divElement.find(".suppress-by-extent").change(function () {
            let legendLayerLis = $('.legend-layer-li');
            if (this.checked) {
                legendLayerLis.removeClass('layer-force-show');
            } else {
                legendLayerLis.addClass('layer-force-show');
            }
        });


        this.$divElement.find('.legend-check').change(function () {
            let lyrId = this.id.replace('-legend-layer-check', '');
            _this.layerGroup.allLayerLookup[lyrId].visible = this.checked;
        });

        this.$divElement.find('.legend-layer-group > input[type=checkbox]').change(function () {
            $(this).siblings('ul').find('input[type=checkbox]').prop('checked', this.checked).trigger('change');
        });

        this.$divElement.find('.layer-group-expander').click(function () {
            let $this = $(this);
            $this.removeClass('legend-layer-group-initial-collapse');

            $this.siblings('ul').slideToggle();

            if ($this.hasClass('legend-layer-group-collapsed')){
                $this.removeClass('legend-layer-group-collapsed');
                $this.html('&amp;#9660;');
            } else {
                $this.addClass('legend-layer-group-collapsed');
                $this.html('&amp;#9654;');
            }
        });

        this.$divElement.find('.legend-layer-group-initial-collapse').trigger('click');
        // &lt;/editor-fold>
    }

    /**
     * @param {Array} [legendItems=this._layerConfig] the legend items
     * @param {Array} [parents=[]] the ordered list of groups in which this item is a member
     * @private
     */
    _buildTree(legendItems, parents) {

        if (legendItems.length == 0) {
            return;
        }

        let oneItem = legendItems[0];

        //reset the parent if the item is in the base array
        if (this._legendItems.indexOf(oneItem) > -1 || typeof parents == 'undefined') {
            parents = [];
        }

        if (typeof oneItem['groupName'] !== 'undefined') {
            let groupItem = legendItems[0];
            let newGroup = this.layerGroup.addGroup(groupItem, parents);
            parents.push(newGroup.groupId);
            this._buildTree(groupItem.items, parents);
        } else {
            /**
             * @type {LayerBase}
             */
            let layerItem = legendItems[0];

            this.layerGroup.addLegendLayer(layerItem, parents);
        }

        this._buildTree(legendItems.slice(1), parents);
    }

    set showAll(val) {

    }
}

nm.LayerLegend = LayerLegend;
export default LayerLegend;
</code></pre>
        </article>
    </section>




</div>

<nav>
Glenn Vorhes's avatar
Glenn Vorhes committed
    <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="-_FeatureLayerProperties.html">_FeatureLayerProperties</a></li><li><a href="-_Slider.html">_Slider</a></li><li><a href="CommonSymbol.html">CommonSymbol</a></li><li><a href="DayRange.html">DayRange</a></li><li><a href="ItsLayerCollection.html">ItsLayerCollection</a></li><li><a href="LayerBase.html">LayerBase</a></li><li><a href="LayerBaseVector.html">LayerBaseVector</a></li><li><a href="LayerBaseVectorEsri.html">LayerBaseVectorEsri</a></li><li><a href="LayerBaseVectorGeoJson.html">LayerBaseVectorGeoJson</a></li><li><a href="LayerBaseXyzTile.html">LayerBaseXyzTile</a></li><li><a href="LayerEsriMapServer.html">LayerEsriMapServer</a></li><li><a href="LayerEsriTile.html">LayerEsriTile</a></li><li><a href="LayerGroup.html">LayerGroup</a></li><li><a href="LayerItsInventory.html">LayerItsInventory</a></li><li><a href="LayerLegend.html">LayerLegend</a></li><li><a href="LayerRealEarthTile.html">LayerRealEarthTile</a></li><li><a href="LayerSwipe.html">LayerSwipe</a></li><li><a href="LayerVectorRealEarth.html">LayerVectorRealEarth</a></li><li><a href="MapInteractionBase.html">MapInteractionBase</a></li><li><a href="MapMoveCls.html">MapMoveCls</a></li><li><a href="MapPopupCls.html">MapPopupCls</a></li><li><a href="RealEarthAnimate.html">RealEarthAnimate</a></li><li><a href="RealEarthAnimateTile.html">RealEarthAnimateTile</a></li><li><a href="RealEarthAnimateVector.html">RealEarthAnimateVector</a></li><li><a href="SingleSymbol.html">SingleSymbol</a></li><li><a href="Sliders.html">Sliders</a></li><li><a href="SortedFeatures.html">SortedFeatures</a></li><li><a href="UniqueValueSymbol.html">UniqueValueSymbol</a></li></ul><h3>Global</h3><ul><li><a href="global.html#$">$</a></li><li><a href="global.html#bundleEs2015Multiple">bundleEs2015Multiple</a></li><li><a href="global.html#calculateExtent">calculateExtent</a></li><li><a href="global.html#dateToYyyyMmDdHh000">dateToYyyyMmDdHh000</a></li><li><a href="global.html#dateToYyyyMmDdHhMmSs">dateToYyyyMmDdHhMmSs</a></li><li><a href="global.html#definedAndNotNull">definedAndNotNull</a></li><li><a href="global.html#defineLegend">defineLegend</a></li><li><a href="global.html#defineStyle">defineStyle</a></li><li><a href="global.html#fitToMap">fitToMap</a></li><li><a href="global.html#getUrlParams">getUrlParams</a></li><li><a href="global.html#gulp">gulp</a></li><li><a href="global.html#hexAlphaToRgbOrRgba">hexAlphaToRgbOrRgba</a></li><li><a href="global.html#htmlEscape">htmlEscape</a></li><li><a href="global.html#keyValPairs">keyValPairs</a></li><li><a href="global.html#makeBlueGreenRedGradient">makeBlueGreenRedGradient</a></li><li><a href="global.html#makeBlueGreenRedGradientZScore">makeBlueGreenRedGradientZScore</a></li><li><a href="global.html#makeFeatureServiceLegendAndSymbol">makeFeatureServiceLegendAndSymbol</a></li><li><a href="global.html#makeGuid">makeGuid</a></li><li><a href="global.html#makeMapServiceLegend">makeMapServiceLegend</a></li><li><a href="global.html#mapServiceLegendItem">mapServiceLegendItem</a></li><li><a href="global.html#offsetMinutes">offsetMinutes</a></li><li><a href="global.html#overflowScroll">overflowScroll</a></li><li><a href="global.html#processLessFile">processLessFile</a></li><li><a href="global.html#propertiesZoomStyle">propertiesZoomStyle</a></li><li><a href="global.html#provide">provide</a></li><li><a href="global.html#quickMap">quickMap</a></li><li><a href="global.html#quickMapBase">quickMapBase</a></li><li><a href="global.html#quickMapMulti">quickMapMulti</a></li><li><a href="global.html#resolutionToZoom">resolutionToZoom</a></li><li><a href="global.html#responsiveScroll">responsiveScroll</a></li><li><a href="global.html#rgb2hex">rgb2hex</a></li><li><a href="global.html#rgbToRgba">rgbToRgba</a></li><li><a href="global.html#triggerCallback">triggerCallback</a></li><li><a href="global.html#undefinedOrNull">undefinedOrNull</a></li><li><a href="global.html#windowScroll">windowScroll</a></li><li><a href="global.html#zoomToResolution">zoomToResolution</a></li></ul>
</nav>

<br class="clear">

<footer>
Glenn Vorhes's avatar
Glenn Vorhes committed
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Mon Jul 18 2016 20:02:34 GMT-0500 (Central Daylight Time)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>