Source: src/js/views/portals/PortalVisualizationsView.js

define(["jquery",
    "underscore",
    "backbone",
    "text!templates/portals/portalVisualizations.html",
    "views/portals/PortalSectionView"],
    function($, _, Backbone, PortalVisualizationsTemplate, PortalSectionView){

    /**
     * @class PortalVisualizationsView
     * @classdesc The PortalVisualizationsView is a view to render the
     * portal visualizations tab (within PortalSectionView)
     * @classcategory Views/Portals
     */
     var PortalVisualizationsView = PortalSectionView.extend(
       /** @lends PortalVisualizationsView.prototype */{

       /**
       * The HTML classes to use for this view's element
       * @type {string}
       */
        className: "portal-viz-section-view tab-pane portal-section-view",

        /**
        * The type of View this is
        * @type {string}
        */
        type: "PortalVisualizations",

        /**
        * The PortalVizSectionModel
        * @type {PortalVizSectionModel}
        */
        model: null,

        /* The list of subview instances contained in this view*/
        subviews: [], // Could be a literal object {}

        /**
        * Renders the compiled template into HTML
        * @type {Underscore.Template}
        */
        template: _.template(PortalVisualizationsTemplate),

        /**
        * Construct a new instance of PortalVisualizationsView
        * @param {Object} options - A literal object with options to pass to the view
        */
        initialize: function(options) {
          // Get all the options and apply them to this view
          if( typeof options == "object" ) {
              var optionKeys = Object.keys(options);
              _.each(optionKeys, function(key, i) {
                  this[key] = options[key];
              }, this);
          }
        },

        /**
        * Renders the view
        */
        render: function() {

          //Attach this view to the DOM element
          this.$el.data("view", this);

          // To speed up the portal load times, visualization content is rendered in the
          // postRender function. This function is called only when a section is active. 
          this.hasRendered = false;

        },

        /**
        * Renders a FEVer visualizattion in this view
        */
        renderFEVer: function(){

          //Exit if FEVer is disabled
          if( !MetacatUI.appModel.get("enableFeverVisualizations") ){
            return;
          }

          //Insert the FEVer visualization into the page
          var iframe = $(document.createElement("iframe"))
                        .attr("src", MetacatUI.appModel.get("feverUrl"))
                        .css("width", "100%");
          this.$el.html(iframe);

        },

        /**
        * Renders a {@link MapView} and inserts into this view
        */
        renderMap: function(){

          //Exit if Cesium is disabled
          if( !MetacatUI.appModel.get("enableCesium") ){
            return;
          }

          let thisView = this;

          //Create a MapView and render it in this view
           require(
              ["views/maps/MapView", "models/maps/Map"],
              function (MapView, Map) {
                
                let mapModel = thisView.model.get("mapModel")
                if (!mapModel) {
                  mapModel = new Map()
                  thisView.model.set("mapModel", mapModel)
                }
                let mapView = new MapView({
                  model: mapModel
                });
                thisView.$el.html(mapView.el);
                mapView.render();
              }
           );

        },

        /**
         * Function called by the PortalView when the section that contains this
         * visualization becomes active (e.g. the user clicks on the section tab). Render
         * the visualization and, if this is a fever viz, adjust the height.
         */
        postRender: function () {
          try {
            if (!this.hasRendered) {
              if( this.model.get("visualizationType") == "fever" ){
                this.renderFEVer();
                this.hasRendered = true;
              }
              else if( this.model.get("visualizationType") == "cesium" ){
                this.renderMap();
                this.hasRendered = true;
              }
            }
  
            if( this.model.get("visualizationType") == "cesium" ){
              document.body.style.setProperty("height", "100%");
            }
            else {
              document.body.style.removeProperty("height");
            }

            if( this.model.get("visualizationType") == "fever" ){
              $(window).resize(this.adjustVizHeight);
              $(".auto-height-member").resize(this.adjustVizHeight);
  
              //Get the height of the visible part of the page for the iframe
              this.adjustVizHeight();
            }
          }
          catch (error) {
            console.log(
              'Failed to render the visualization in the PortalVisualizationsView ' +
              'postRender function. Error details: ' + error
            );
          }
        },

        adjustVizHeight: function(){
          // Get the heights of the header, navbar, and footer
          var otherHeight = 0;
          $(".auto-height-member").each(function(i, el) {
              if ($(el).css("display") != "none" && !$(el).is("#Footer") ) {
                  otherHeight += $(el).outerHeight(true);
              }
          });

          // Get the remaining height left based on the window size
          var remainingHeight = $(window).outerHeight(true) - otherHeight;
          if (remainingHeight < 0){
            remainingHeight = $(window).outerHeight(true) || 600;
          }
          else if (remainingHeight <= 120){
            remainingHeight = ($(window).outerHeight(true) - remainingHeight) || 600;
          }

          this.$("iframe").css("height", remainingHeight + "px");
        },

        /**
         * Clean up
         */
        onClose: function() {
          // Remove body height style tag
          document.body.style.removeProperty("height");

          // this is failing for Cesium pages but might be necessary in FEVer ones
          try {
            $(window).removeListener("resize", this.adjustVizHeight);
          }
          catch (error) {
            console.log(
              'Failed to remove resize listener in portal viz onClose function. ' +
              'Error details: ' + error
            );
          }
        }

     });

     return PortalVisualizationsView;
});