You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ma...@apache.org on 2013/02/04 03:24:02 UTC

svn commit: r1442010 [26/29] - in /incubator/ambari/branches/branch-1.2: ./ ambari-agent/ ambari-agent/conf/unix/ ambari-agent/src/examples/ ambari-agent/src/main/puppet/modules/hdp-ganglia/files/ ambari-agent/src/main/puppet/modules/hdp-ganglia/manife...

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/chart/linear_time.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/chart/linear_time.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/chart/linear_time.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/chart/linear_time.js Mon Feb  4 02:23:55 2013
@@ -46,553 +46,578 @@ var string_utils = require('utils/string
  * @extends Ember.View
  */
 App.ChartLinearTimeView = Ember.View.extend({
-      templateName: require('templates/main/charts/linear_time'),
+  templateName: require('templates/main/charts/linear_time'),
 
-      /**
-       * The URL from which data can be retrieved.
-       * 
-       * This property must be provided for the graph to show properly.
-       * 
-       * @type String
-       * @default null
-       */
-      url: null,
-
-      /**
-       * A unique ID for this chart.
-       * 
-       * @type String
-       * @default null
-       */
-      id: null,
-
-      /**
-       * Title to be shown under the chart.
-       * 
-       * @type String
-       * @default null
-       */
-      title: null,
-
-      /**
-       * @private
-       * 
-       * @type Rickshaw.Graph
-       * @default null
-       */
-      _graph: null,
-
-      _popupGraph: null,
-
-      _seriesProperties: null,
-
-      renderer: 'area',
-
-      popupSuffix: '-popup',
-
-      isPopup: false,
-
-      isReady: false,
-
-      isPopupReady: false,
-
-      hasData: true,
-
-      /**
-       * Color palette used for this chart
-       *
-       * @private
-       * @type String[]
-       */
-       /*
-      _paletteScheme: [ 'rgba(181,182,169,0.4)', 'rgba(133,135,114,0.4)',
-          'rgba(120,95,67,0.4)', 'rgba(150,85,126,0.4)',
-          'rgba(70,130,180,0.4)', 'rgba(0,255,204,0.4)',
-          'rgba(255,105,180,0.4)', 'rgba(101,185,172,0.4)',
-          'rgba(115,192,58,0.4)', 'rgba(203,81,58,0.4)' ].reverse(),
-      */
-
-      selector: function () {
-        return '#' + this.get('elementId');
-      }.property('elementId'),
-
-      didInsertElement: function () {
-        this.loadData();
-        this.registerGraph();
-      },
-      registerGraph: function(){
-        var graph = {
-          name: this.get('title'),
-          id: this.get('elementId'),
-          popupId: this.get('id')
-        };
-        App.router.get('updateController.graphs').push(graph);
-      },
-
-      loadData: function() {
-        var validUrl = this.get('url');
-        if (validUrl) {
-          var hash = {};
-          hash.url = validUrl;
-          hash.type = 'GET';
-          hash.dataType = 'json';
-          hash.contentType = 'application/json; charset=utf-8';
-          hash.context = this;
-          hash.success = this._refreshGraph,
-           hash.error = function(xhr, textStatus, errorThrown){
-            this.set('isReady', true);
-            if (xhr.readyState == 4 && xhr.status) {
-              textStatus = xhr.status + " " + textStatus;
-            }
-            this._showMessage('warn', this.t('graphs.error.title'), this.t('graphs.error.message').format(textStatus, errorThrown));
-            this.set('isPopup', false);
-            this.set('hasData', false);
-          }
-          jQuery.ajax(hash);
-        }
-      },
-      
-      /**
-       * Shows a yellow warning message in place of the chart.
-       * 
-       * @param type  Can be any of 'warn', 'error', 'info', 'success'
-       * @param title Bolded title for the message
-       * @param message String representing the message
-       * @type: Function
-       */
-      _showMessage: function(type, title, message){
-        var chartOverlayId = '#' + this.id + '-chart';
-        if (this.get('isPopup')) {
-          chartOverlayId += this.get('popupSuffix');
-        }
-        var typeClass;
-        switch (type) {
-          case 'error':
-            typeClass = 'alert-error';
-            break;
-          case 'success':
-            typeClass = 'alert-success';
-            break;
-          case 'info':
-            typeClass = 'alert-info';
-            break;
-          default:
-            typeClass = '';
-            break;
-        }
-        $(chartOverlayId).html('');
-        $(chartOverlayId).append('<div class=\"alert '+typeClass+'\"><strong>'+title+'</strong> '+message+'</div>');
-      },
-
-      /**
-       * Transforms the JSON data retrieved from the server into the series
-       * format that Rickshaw.Graph understands.
-       * 
-       * The series object is generally in the following format: [ { name :
-       * "Series 1", data : [ { x : 0, y : 0 }, { x : 1, y : 1 } ] } ]
-       * 
-       * Extending classes should override this method.
-       * 
-       * @param jsonData
-       *          Data retrieved from the server
-       * @type: Function
-       * 
-       */
-      transformToSeries: function (jsonData) {
-        return [ {
-          name: "Series 1",
-          data: [ {
-            x: 0,
-            y: 0
-          }, {
-            x: 1,
-            y: 1
-          } ]
-        } ]
-      },
-
-      /**
-       * Provides the formatter to use in displaying Y axis.
-       * 
-       * The default is Rickshaw.Fixtures.Number.formatKMBT which shows 10K,
-       * 300M etc.
-       * 
-       * @type Function
-       */
-      yAxisFormatter: function(y) {
-        var value = Rickshaw.Fixtures.Number.formatKMBT(y);
-        if (value == '') return '0';
-        value = String(value);
-        var c = value[value.length - 1];
-        if (!isNaN(parseInt(c))) {
-          // c is digit
-          value = parseFloat(value).toFixed(3).replace(/0+$/, '').replace(/\.$/, '');
-        }
-        else {
-          // c in not digit
-          value = parseFloat(value.substr(0, value.length - 1)).toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + c;
+  /**
+   * The URL from which data can be retrieved.
+   *
+   * This property must be provided for the graph to show properly.
+   *
+   * @type String
+   * @default null
+   */
+  url: null,
+
+  /**
+   * A unique ID for this chart.
+   *
+   * @type String
+   * @default null
+   */
+  id: null,
+
+  /**
+   * Title to be shown under the chart.
+   *
+   * @type String
+   * @default null
+   */
+  title: null,
+
+  /**
+   * @private
+   *
+   * @type Rickshaw.Graph
+   * @default null
+   */
+  _graph: null,
+
+  _popupGraph: null,
+
+  _seriesProperties: null,
+
+  renderer: 'area',
+
+  popupSuffix: '-popup',
+
+  isPopup: false,
+
+  isReady: false,
+
+  isPopupReady: false,
+
+  hasData: true,
+  /**
+   * Current cluster name
+   */
+  clusterName: function() {
+    return App.router.get('clusterController.clusterName');
+  }.property('App.router.clusterController.clusterName'),
+  /**
+   * Url prefix common for all child views
+   */
+  urlPrefix: function() {
+    return App.apiPrefix + "/clusters/" + this.get('clusterName');
+  }.property('clusterName'),
+
+  /**
+   * Color palette used for this chart
+   *
+   * @private
+   * @type String[]
+   */
+   /*
+  _paletteScheme: [ 'rgba(181,182,169,0.4)', 'rgba(133,135,114,0.4)',
+      'rgba(120,95,67,0.4)', 'rgba(150,85,126,0.4)',
+      'rgba(70,130,180,0.4)', 'rgba(0,255,204,0.4)',
+      'rgba(255,105,180,0.4)', 'rgba(101,185,172,0.4)',
+      'rgba(115,192,58,0.4)', 'rgba(203,81,58,0.4)' ].reverse(),
+  */
+
+  selector: function () {
+    return '#' + this.get('elementId');
+  }.property('elementId'),
+
+  didInsertElement: function () {
+    this.loadData();
+    this.registerGraph();
+  },
+  registerGraph: function(){
+    var graph = {
+      name: this.get('title'),
+      id: this.get('elementId'),
+      popupId: this.get('id')
+    };
+    App.router.get('updateController.graphs').push(graph);
+  },
+
+  loadData: function() {
+    var validUrl = this.get('url');
+    if (validUrl) {
+      var hash = {};
+      hash.url = validUrl;
+      hash.type = 'GET';
+      hash.dataType = 'json';
+      hash.contentType = 'application/json; charset=utf-8';
+      hash.context = this;
+      hash.success = this._refreshGraph,
+       hash.error = function(xhr, textStatus, errorThrown){
+        this.set('isReady', true);
+        if (xhr.readyState == 4 && xhr.status) {
+          textStatus = xhr.status + " " + textStatus;
         }
-        return value;
-      },
+        this._showMessage('warn', this.t('graphs.error.title'), this.t('graphs.error.message').format(textStatus, errorThrown));
+        this.set('isPopup', false);
+        this.set('hasData', false);
+      }
+      jQuery.ajax(hash);
+    }
+  },
 
-      /**
-       * Provides the color (in any HTML color format) to use for a particular
-       * series.
-       *
-       * @param series
-       *          Series for which color is being requested
-       * @return color String. Returning null allows this chart to pick a color
-       *         from palette.
-       * @default null
-       * @type Function
-       */
-      colorForSeries: function (series) {
-        return null;
-      },
+  /**
+   * Shows a yellow warning message in place of the chart.
+   *
+   * @param type  Can be any of 'warn', 'error', 'info', 'success'
+   * @param title Bolded title for the message
+   * @param message String representing the message
+   * @type: Function
+   */
+  _showMessage: function(type, title, message){
+    var chartOverlayId = '#' + this.id + '-chart';
+    if (this.get('isPopup')) {
+      chartOverlayId += this.get('popupSuffix');
+    }
+    var typeClass;
+    switch (type) {
+      case 'error':
+        typeClass = 'alert-error';
+        break;
+      case 'success':
+        typeClass = 'alert-success';
+        break;
+      case 'info':
+        typeClass = 'alert-info';
+        break;
+      default:
+        typeClass = '';
+        break;
+    }
+    $(chartOverlayId).html('');
+    $(chartOverlayId).append('<div class=\"alert '+typeClass+'\"><strong>'+title+'</strong> '+message+'</div>');
+  },
 
   /**
-   * Check whether seriesData is correct data for chart drawing
+   * Transforms the JSON data retrieved from the server into the series
+   * format that Rickshaw.Graph understands.
+   *
+   * The series object is generally in the following format: [ { name :
+   * "Series 1", data : [ { x : 0, y : 0 }, { x : 1, y : 1 } ] } ]
+   *
+   * Extending classes should override this method.
+   *
    * @param seriesData
-   * @return {Boolean}
+   *          Data retrieved from the server
+   * @param displayName
+   *          Graph title
+   * @type: Function
+   *
    */
-      checkSeries : function(seriesData){
-        if(!seriesData || !seriesData.length){
-          return false;
-        }
-        var result = true;
-        seriesData.forEach(function(item){
-          if(!item.data.length || !item.data[0] || typeof item.data[0].x === 'undefined'){
-            result = false;
-          }
+  transformData: function (seriesData, displayName) {
+    var seriesArray = [];
+    if (seriesData) {
+      // Is it a string?
+      if ("string" == typeof seriesData) {
+        seriesData = JSON.parse(seriesData);
+      }
+      // We have valid data
+      var series = {};
+      series.name = displayName;
+      series.data = [];
+      for ( var index = 0; index < seriesData.length; index++) {
+        series.data.push({
+          x: seriesData[index][1],
+          y: seriesData[index][0]
         });
-        return result;
-      },
+      }
+      return series;
+    }
+  },
 
-      /**
-       * @private
-       * 
-       * Refreshes the graph with the latest JSON data.
-       * 
-       * @type Function
-       */
-      _refreshGraph: function (jsonData) {
-        var seriesData = this.transformToSeries(jsonData);
-
-        if (this.checkSeries(seriesData)) {
-          //if graph opened as modal popup
-          var popup_path = $("#" + this.id + "-container" + this.get('popupSuffix'));
-          var graph_container = $("#" + this.id + "-container");
-          if(popup_path.length) {
-            popup_path.children().each(function () {
-              $(this).children().remove();
-            });
-            this.set('isPopup', true);
-          }
-          else {
-            graph_container.children().each(function (index, value) {
-              $(value).children().remove();
-            });
-          }
-          // Check container exists (may be not, if we go to another page and wait while graphs loading)
-          if (graph_container.length) {
-            this.draw(seriesData);
-            this.set('hasData', true);
-          }
-        }
-        else {
-          this.set('isReady', true);
-          this._showMessage('info', this.t('graphs.noData.title'), this.t('graphs.noData.message'));
-          this.set('isPopup', false);
-          this.set('hasData', false);
-        }
-      },
-      
-      /**
-       * Returns a custom time unit for the graph's X axis. This is needed
-       * as Rickshaw's default time X axis uses UTC time, which can be confusing
-       * for users expecting locale specific time. This value defaults to
-       * App.ChartLinearTimeView.FifteenMinuteTimeUnit.
-       * 
-       * If <code>null</code> is returned, Rickshaw's default time unit is used.
-       * 
-       * @type Function
-       * @return Rickshaw.Fixtures.Time
-       * @default App.ChartLinearTimeView.FifteenMinuteTimeUnit
-       */
-      localeTimeUnit: function(){
-        return App.ChartLinearTimeView.FifteenMinuteTimeUnit;
-      },
-
-      /**
-       * @private
-       * 
-       * When a graph is given a particular width and height,the lines are drawn
-       * in a slightly bigger area thereby chopping off some of the UI. Hence
-       * after the rendering, we adjust the SVGs size in the DOM to compensate.
-       * 
-       * Opened https://github.com/shutterstock/rickshaw/issues/141
-       * 
-       * @type Function
-       */
-      _adjustSVGHeight: function () {
-        if (this._graph && this._graph.element
-            && this._graph.element.firstChild) {
-          var svgElement = this._graph.element.firstChild;
-          svgElement.setAttribute('height', $(this._graph.element).height()
-              + "px");
-          svgElement.setAttribute('width', $(this._graph.element).width()
-              + "px");
-        }
-      },
+  /**
+   * Provides the formatter to use in displaying Y axis.
+   *
+   * The default is Rickshaw.Fixtures.Number.formatKMBT which shows 10K,
+   * 300M etc.
+   *
+   * @type Function
+   */
+  yAxisFormatter: function(y) {
+    var value = Rickshaw.Fixtures.Number.formatKMBT(y);
+    if (value == '') return '0';
+    value = String(value);
+    var c = value[value.length - 1];
+    if (!isNaN(parseInt(c))) {
+      // c is digit
+      value = parseFloat(value).toFixed(3).replace(/0+$/, '').replace(/\.$/, '');
+    }
+    else {
+      // c in not digit
+      value = parseFloat(value.substr(0, value.length - 1)).toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + c;
+    }
+    return value;
+  },
 
-      draw: function(seriesData) {
-        var isPopup = this.get('isPopup');
-        var p = '';
-        if (isPopup) {
-          p = this.get('popupSuffix');
-        }
-        var palette = new Rickshaw.Color.Palette({ scheme: 'munin'});
+  /**
+   * Provides the color (in any HTML color format) to use for a particular
+   * series.
+   *
+   * @param series
+   *          Series for which color is being requested
+   * @return color String. Returning null allows this chart to pick a color
+   *         from palette.
+   * @default null
+   * @type Function
+   */
+  colorForSeries: function (series) {
+    return null;
+  },
 
-        // var palette = new Rickshaw.Color.Palette({
-        //   scheme: this._paletteScheme
-        // });
-
-        var self = this;
-        var series_min_length = 100000000;
-        seriesData.forEach(function (series, index) {
-          var seriesColor = self.colorForSeries(series);
-          if (seriesColor == null) {
-            seriesColor = palette.color();
-          }
-          series.color = seriesColor;
-          series.stroke = 'rgba(0,0,0,0.3)';
-          if (isPopup) {
-            // calculate statistic data for popup legend
-            var avg = 0;
-            var min = Number.MAX_VALUE;
-            var max = Number.MIN_VALUE;
-            for (var i = 0; i < series.data.length; i++) {
-              avg += series.data[i]['y'];
-              if (series.data[i]['y'] < min) {
-                min = series.data[i]['y'];
-              }
-              else {
-                if (series.data[i]['y'] > max) {
-                  max = series.data[i]['y'];
-                }
-              }
-            }
-            series.name = string_utils.pad(series.name, 30, '&nbsp;', 2) + string_utils.pad('min', 5, '&nbsp;', 3) + string_utils.pad(this.get('yAxisFormatter')(min), 12, '&nbsp;', 3) + string_utils.pad('avg', 5, '&nbsp;', 3) + string_utils.pad(this.get('yAxisFormatter')(avg/series.data.length), 12, '&nbsp;', 3) + string_utils.pad('max', 12, '&nbsp;', 3) + string_utils.pad(this.get('yAxisFormatter')(max), 5, '&nbsp;', 3);
-          }
-          if (series.data.length < series_min_length) {
-            series_min_length = series.data.length;
-          }
-        }.bind(this));
-        seriesData.forEach(function(series, index) {
-          if (series.data.length > series_min_length) {
-            series.data.length = series_min_length;
-          }
+  /**
+  * Check whether seriesData is correct data for chart drawing
+  * @param seriesData
+  * @return {Boolean}
+  */
+  checkSeries : function(seriesData){
+    if(!seriesData || !seriesData.length){
+      return false;
+    }
+    var result = true;
+    seriesData.forEach(function(item){
+      if(!item.data.length || !item.data[0] || typeof item.data[0].x === 'undefined'){
+        result = false;
+      }
+    });
+    return result;
+  },
+
+  /**
+   * @private
+   *
+   * Refreshes the graph with the latest JSON data.
+   *
+   * @type Function
+   */
+  _refreshGraph: function (jsonData) {
+    if(this.get('isDestroyed')){
+      return;
+    }
+    var seriesData = this.transformToSeries(jsonData);
+
+    if (this.checkSeries(seriesData)) {
+      //if graph opened as modal popup
+      var popup_path = $("#" + this.id + "-container" + this.get('popupSuffix'));
+      var graph_container = $("#" + this.id + "-container");
+      if(popup_path.length) {
+        popup_path.children().each(function () {
+          $(this).children().remove();
         });
-        var chartId = "#" + this.id + "-chart" + p;
-        var chartOverlayId = "#" + this.id + "-container" + p;
-        var xaxisElementId = "#" + this.id + "-xaxis" + p;
-        var yaxisElementId = "#" + this.id + "-yaxis" + p;
-        var legendElementId = "#" + this.id + "-legend" + p;
-
-        var chartElement = document.querySelector(chartId);
-        var overlayElement = document.querySelector(chartOverlayId);
-        var xaxisElement = document.querySelector(xaxisElementId);
-        var yaxisElement = document.querySelector(yaxisElementId);
-        var legendElement = document.querySelector(legendElementId);
-
-        var strokeWidth = 1;
-        if (this.get('renderer') != 'area') {
-          strokeWidth = 2;
-        }
+        this.set('isPopup', true);
+      }
+      else {
+        graph_container.children().each(function (index, value) {
+          $(value).children().remove();
+        });
+      }
+      // Check container exists (may be not, if we go to another page and wait while graphs loading)
+      if (graph_container.length) {
+        this.draw(seriesData);
+        this.set('hasData', true);
+      }
+    }
+    else {
+      this.set('isReady', true);
+      this._showMessage('info', this.t('graphs.noData.title'), this.t('graphs.noData.message'));
+      this.set('isPopup', false);
+      this.set('hasData', false);
+    }
+  },
+
+  /**
+   * Returns a custom time unit for the graph's X axis. This is needed
+   * as Rickshaw's default time X axis uses UTC time, which can be confusing
+   * for users expecting locale specific time. This value defaults to
+   * App.ChartLinearTimeView.FifteenMinuteTimeUnit.
+   *
+   * If <code>null</code> is returned, Rickshaw's default time unit is used.
+   *
+   * @type Function
+   * @return Rickshaw.Fixtures.Time
+   * @default App.ChartLinearTimeView.FifteenMinuteTimeUnit
+   */
+  localeTimeUnit: function(){
+    return App.ChartLinearTimeView.FifteenMinuteTimeUnit;
+  },
+
+  /**
+   * @private
+   *
+   * When a graph is given a particular width and height,the lines are drawn
+   * in a slightly bigger area thereby chopping off some of the UI. Hence
+   * after the rendering, we adjust the SVGs size in the DOM to compensate.
+   *
+   * Opened https://github.com/shutterstock/rickshaw/issues/141
+   *
+   * @type Function
+   */
+  _adjustSVGHeight: function () {
+    if (this._graph && this._graph.element
+        && this._graph.element.firstChild) {
+      var svgElement = this._graph.element.firstChild;
+      svgElement.setAttribute('height', $(this._graph.element).height()
+          + "px");
+      svgElement.setAttribute('width', $(this._graph.element).width()
+          + "px");
+    }
+  },
+
+  draw: function(seriesData) {
+    var isPopup = this.get('isPopup');
+    var p = '';
+    if (isPopup) {
+      p = this.get('popupSuffix');
+    }
+    var palette = new Rickshaw.Color.Palette({ scheme: 'munin'});
 
-        var height = 150;
-        var width = 400;
-        if (isPopup) {
-          height = 180;
-          width = 670;
-        } else {
-          // If not in popup, the width could vary.
-          // We determine width based on div's size.
-          var thisElement = this.get('element');
-          if (thisElement!=null) {
-            var calculatedWidth = $(thisElement).width();
-            if (calculatedWidth > 32) {
-              width = calculatedWidth-32;
+    // var palette = new Rickshaw.Color.Palette({
+    //   scheme: this._paletteScheme
+    // });
+
+    var self = this;
+    var series_min_length = 100000000;
+    seriesData.forEach(function (series, index) {
+      var seriesColor = self.colorForSeries(series);
+      if (seriesColor == null) {
+        seriesColor = palette.color();
+      }
+      series.color = seriesColor;
+      series.stroke = 'rgba(0,0,0,0.3)';
+      if (isPopup) {
+        // calculate statistic data for popup legend
+        var avg = 0;
+        var min = Number.MAX_VALUE;
+        var max = Number.MIN_VALUE;
+        for (var i = 0; i < series.data.length; i++) {
+          avg += series.data[i]['y'];
+          if (series.data[i]['y'] < min) {
+            min = series.data[i]['y'];
+          }
+          else {
+            if (series.data[i]['y'] > max) {
+              max = series.data[i]['y'];
             }
           }
         }
-        var _graph = new Rickshaw.Graph({
-          height: height,
-          width: width,
-          element: chartElement,
-          series: seriesData,
-          interpolation: 'step-after',
-          stroke: true,
-          renderer: this.get('renderer'),
-          strokeWidth: strokeWidth
-        });
-        if (this.get('renderer') === 'area') {
-          _graph.renderer.unstack = false;
+        series.name = string_utils.pad(series.name, 30, '&nbsp;', 2) + string_utils.pad('min', 5, '&nbsp;', 3) + string_utils.pad(this.get('yAxisFormatter')(min), 12, '&nbsp;', 3) + string_utils.pad('avg', 5, '&nbsp;', 3) + string_utils.pad(this.get('yAxisFormatter')(avg/series.data.length), 12, '&nbsp;', 3) + string_utils.pad('max', 12, '&nbsp;', 3) + string_utils.pad(this.get('yAxisFormatter')(max), 5, '&nbsp;', 3);
+      }
+      if (series.data.length < series_min_length) {
+        series_min_length = series.data.length;
+      }
+    }.bind(this));
+    seriesData.forEach(function(series, index) {
+      if (series.data.length > series_min_length) {
+        series.data.length = series_min_length;
+      }
+    });
+    var chartId = "#" + this.id + "-chart" + p;
+    var chartOverlayId = "#" + this.id + "-container" + p;
+    var xaxisElementId = "#" + this.id + "-xaxis" + p;
+    var yaxisElementId = "#" + this.id + "-yaxis" + p;
+    var legendElementId = "#" + this.id + "-legend" + p;
+
+    var chartElement = document.querySelector(chartId);
+    var overlayElement = document.querySelector(chartOverlayId);
+    var xaxisElement = document.querySelector(xaxisElementId);
+    var yaxisElement = document.querySelector(yaxisElementId);
+    var legendElement = document.querySelector(legendElementId);
+
+    var strokeWidth = 1;
+    if (this.get('renderer') != 'area') {
+      strokeWidth = 2;
+    }
+
+    var height = 150;
+    var width = 400;
+    if (isPopup) {
+      height = 180;
+      width = 670;
+    } else {
+      // If not in popup, the width could vary.
+      // We determine width based on div's size.
+      var thisElement = this.get('element');
+      if (thisElement!=null) {
+        var calculatedWidth = $(thisElement).width();
+        if (calculatedWidth > 32) {
+          width = calculatedWidth-32;
         }
+      }
+    }
+    var _graph = new Rickshaw.Graph({
+      height: height,
+      width: width,
+      element: chartElement,
+      series: seriesData,
+      interpolation: 'step-after',
+      stroke: true,
+      renderer: this.get('renderer'),
+      strokeWidth: strokeWidth
+    });
+    if (this.get('renderer') === 'area') {
+      _graph.renderer.unstack = false;
+    }
 
-        xAxis = new Rickshaw.Graph.Axis.Time({
-          graph: _graph,
-          timeUnit: this.localeTimeUnit()
-        });
+    xAxis = new Rickshaw.Graph.Axis.Time({
+      graph: _graph,
+      timeUnit: this.localeTimeUnit()
+    });
 
-        var orientation = 'right';
-        if (isPopup) {
-          orientation = 'left';
-        }
-        yAxis = new Rickshaw.Graph.Axis.Y({
-          tickFormat: this.yAxisFormatter,
-          element: yaxisElement,
-          orientation: orientation,
-          graph: _graph
-        });
+    var orientation = 'right';
+    if (isPopup) {
+      orientation = 'left';
+    }
+    yAxis = new Rickshaw.Graph.Axis.Y({
+      tickFormat: this.yAxisFormatter,
+      element: yaxisElement,
+      orientation: orientation,
+      graph: _graph
+    });
 
-        var legend = new Rickshaw.Graph.Legend({
-          graph: _graph,
-          element: legendElement
-        });
+    var legend = new Rickshaw.Graph.Legend({
+      graph: _graph,
+      element: legendElement
+    });
 
-        if (!isPopup) {
-          overlayElement.addEventListener('mousemove', function () {
-            $(xaxisElement).removeClass('hide');
-            $(legendElement).removeClass('hide');
-            $(chartElement).children("div").removeClass('hide');
-          });
-          overlayElement.addEventListener('mouseout', function () {
-            $(legendElement).addClass('hide');
-          });
-          _graph.onUpdate(function () {
-            $(legendElement).addClass('hide');
-          });
-        }
+    if (!isPopup) {
+      overlayElement.addEventListener('mousemove', function () {
+        $(xaxisElement).removeClass('hide');
+        $(legendElement).removeClass('hide');
+        $(chartElement).children("div").removeClass('hide');
+      });
+      overlayElement.addEventListener('mouseout', function () {
+        $(legendElement).addClass('hide');
+      });
+      _graph.onUpdate(function () {
+        $(legendElement).addClass('hide');
+      });
+    }
 
-       var shelving = new Rickshaw.Graph.Behavior.Series.Toggle({
-          graph: _graph,
-          legend: legend
-        });
+   var shelving = new Rickshaw.Graph.Behavior.Series.Toggle({
+      graph: _graph,
+      legend: legend
+    });
 
-        var order = new Rickshaw.Graph.Behavior.Series.Order({
-          graph: _graph,
-          legend: legend
-        });
-        //show the graph when it's loaded
-        _graph.onUpdate(function(){
-          self.set('isReady', true);
-        });
-        _graph.render();
+    var order = new Rickshaw.Graph.Behavior.Series.Order({
+      graph: _graph,
+      legend: legend
+    });
+    //show the graph when it's loaded
+    _graph.onUpdate(function(){
+      self.set('isReady', true);
+    });
+    _graph.render();
 
-        if (isPopup) {
-          var self = this;
-          var hoverDetail = new Rickshaw.Graph.HoverDetail({
-            graph: _graph,
-            yFormatter:function (y) {
-              return self.yAxisFormatter(y);
-            },
-            xFormatter:function (x) {
-              return (new Date(x * 1000)).toLocaleTimeString();
-            },
-            formatter:function (series, x, y, formattedX, formattedY, d) {
-              return formattedY + '<br />' + formattedX;
-            }
-          });
+    if (isPopup) {
+      var self = this;
+      var hoverDetail = new Rickshaw.Graph.HoverDetail({
+        graph: _graph,
+        yFormatter:function (y) {
+          return self.yAxisFormatter(y);
+        },
+        xFormatter:function (x) {
+          return (new Date(x * 1000)).toLocaleTimeString();
+        },
+        formatter:function (series, x, y, formattedX, formattedY, d) {
+          return formattedY + '<br />' + formattedX;
         }
+      });
+    }
 
-        if (isPopup) {
-          var self = this;
-          // In popup save selected metrics and show only them after data update
-          _graph.series.forEach(function(series, index) {
-            if (self.get('_seriesProperties') !== null && self.get('_seriesProperties')[index] !== null) {
-              if(self.get('_seriesProperties')[self.get('_seriesProperties').length - index - 1].length > 1) {
-                $('#'+self.get('id')+'-container'+self.get('popupSuffix')+' a.action:eq('+(self.get('_seriesProperties').length - index - 1)+')').parent('li').addClass('disabled');
-                series.disable();
-              }
-            }
-          });
-          //show the graph when it's loaded
-          _graph.onUpdate(function(){
-            self.set('isPopupReady', true);
-          });
-          _graph.update();
-
-          $('li.line').click(function() {
-            var series = [];
-            $('#'+self.get('id')+'-container'+self.get('popupSuffix')+' a.action').each(function(index, v) {
-              series[index] = v.parentNode.classList;
-            });
-            self.set('_seriesProperties', series);
-          });
+    if (isPopup) {
+      var self = this;
+      // In popup save selected metrics and show only them after data update
+      _graph.series.forEach(function(series, index) {
+        if (self.get('_seriesProperties') !== null && self.get('_seriesProperties')[index] !== null) {
+          if(self.get('_seriesProperties')[self.get('_seriesProperties').length - index - 1].length > 1) {
+            $('#'+self.get('id')+'-container'+self.get('popupSuffix')+' a.action:eq('+(self.get('_seriesProperties').length - index - 1)+')').parent('li').addClass('disabled');
+            series.disable();
+          }
+        }
+      });
+      //show the graph when it's loaded
+      _graph.onUpdate(function(){
+        self.set('isPopupReady', true);
+      });
+      _graph.update();
+
+      $('li.line').click(function() {
+        var series = [];
+        $('#'+self.get('id')+'-container'+self.get('popupSuffix')+' a.action').each(function(index, v) {
+          series[index] = v.parentNode.classList;
+        });
+        self.set('_seriesProperties', series);
+      });
 
-          this.set('_popupGraph', _graph);
-        }
-        else {
-          this.set('_graph', _graph);
-        }
-        this.set('isPopup', false);
-      },
+      this.set('_popupGraph', _graph);
+    }
+    else {
+      this.set('_graph', _graph);
+    }
+    this.set('isPopup', false);
+  },
 
 
-      showGraphInPopup: function() {
-        if(!this.get('hasData')){
-          return;
-        }
+  showGraphInPopup: function() {
+    if(!this.get('hasData')){
+      return;
+    }
 
-        this.set('isPopup', true);
-        var self = this;
-        App.ModalPopup.show({
-          template: Ember.Handlebars.compile([
-            '<div class="modal-backdrop"></div><div class="modal modal-graph-line" id="modal" tabindex="-1" role="dialog" aria-labelledby="modal-label" aria-hidden="true">',
-            '<div class="modal-header">',
-            '<a class="close" {{action onClose target="view"}}>x</a>',
-            '<h3 id="modal-label">',
-            '{{#if headerClass}}{{view headerClass}}',
-            '{{else}}{{header}}{{/if}}',
-            '</h3>',
-            '</div>',
-            '<div class="modal-body">',
-            '{{#if bodyClass}}{{view bodyClass}}',
-            '{{else}}',
-              '<div class="screensaver no-borders chart-container" {{bindAttr class="view.isReady:hide"}} ></div>',
-              '<div id="'+this.get('id')+'-container'+this.get('popupSuffix')+'" class="chart-container chart-container'+this.get('popupSuffix')+' hide" {{bindAttr class="view.isReady:show"}} >',
-                '<div id="'+this.get('id')+'-yaxis'+this.get('popupSuffix')+'" class="'+this.get('id')+'-yaxis chart-y-axis"></div>',
-                '<div id="'+this.get('id')+'-xaxis'+this.get('popupSuffix')+'" class="'+this.get('id')+'-xaxis chart-x-axis"></div>',
-                '<div id="'+this.get('id')+'-legend'+this.get('popupSuffix')+'" class="'+this.get('id')+'-legend chart-legend"></div>',
-                '<div id="'+this.get('id')+'-chart'+this.get('popupSuffix')+'" class="'+this.get('id')+'-chart chart"></div>',
-                '<div id="'+this.get('id')+'-title'+this.get('popupSuffix')+'" class="'+this.get('id')+'-title chart-title">{{view.title}}</div>'+
-              '</div>',
-            '{{/if}}',
-            '</div>',
-            '<div class="modal-footer">',
-            '{{#if view.primary}}<a class="btn btn-success" {{action onPrimary target="view"}}>{{view.primary}}</a>{{/if}}',
-            '</div>',
-            '</div>'
-          ].join('\n')),
-
-          header: this.get('title'),
-          self: self,
-          isReady: function(){
-            return this.get('self.isPopupReady');
-          }.property('self.isPopupReady'),
-          primary: 'OK',
-          onPrimary: function() {
-            this.hide();
-            self.set('isPopup', false);
-          }
-        });
-        Ember.run.next(function() {
-          self.loadData();
-          self.set('isPopupReady', false);
-        });
+    this.set('isPopup', true);
+    var self = this;
+    App.ModalPopup.show({
+      template: Ember.Handlebars.compile([
+        '<div class="modal-backdrop"></div><div class="modal modal-graph-line" id="modal" tabindex="-1" role="dialog" aria-labelledby="modal-label" aria-hidden="true">',
+        '<div class="modal-header">',
+        '<a class="close" {{action onClose target="view"}}>x</a>',
+        '<h3 id="modal-label">',
+        '{{#if headerClass}}{{view headerClass}}',
+        '{{else}}{{header}}{{/if}}',
+        '</h3>',
+        '</div>',
+        '<div class="modal-body">',
+        '{{#if bodyClass}}{{view bodyClass}}',
+        '{{else}}',
+          '<div class="screensaver no-borders chart-container" {{bindAttr class="view.isReady:hide"}} ></div>',
+          '<div id="'+this.get('id')+'-container'+this.get('popupSuffix')+'" class="chart-container chart-container'+this.get('popupSuffix')+' hide" {{bindAttr class="view.isReady:show"}} >',
+            '<div id="'+this.get('id')+'-yaxis'+this.get('popupSuffix')+'" class="'+this.get('id')+'-yaxis chart-y-axis"></div>',
+            '<div id="'+this.get('id')+'-xaxis'+this.get('popupSuffix')+'" class="'+this.get('id')+'-xaxis chart-x-axis"></div>',
+            '<div id="'+this.get('id')+'-legend'+this.get('popupSuffix')+'" class="'+this.get('id')+'-legend chart-legend"></div>',
+            '<div id="'+this.get('id')+'-chart'+this.get('popupSuffix')+'" class="'+this.get('id')+'-chart chart"></div>',
+            '<div id="'+this.get('id')+'-title'+this.get('popupSuffix')+'" class="'+this.get('id')+'-title chart-title">{{view.title}}</div>'+
+          '</div>',
+        '{{/if}}',
+        '</div>',
+        '<div class="modal-footer">',
+        '{{#if view.primary}}<a class="btn btn-success" {{action onPrimary target="view"}}>{{view.primary}}</a>{{/if}}',
+        '</div>',
+        '</div>'
+      ].join('\n')),
+
+      header: this.get('title'),
+      self: self,
+      isReady: function(){
+        return this.get('self.isPopupReady');
+      }.property('self.isPopupReady'),
+      primary: 'OK',
+      onPrimary: function() {
+        this.hide();
+        self.set('isPopup', false);
       }
     });
+    Ember.run.next(function() {
+      self.loadData();
+      self.set('isPopupReady', false);
+    });
+  }
+});
 
 /**
  * A formatter which will turn a number into computer storage sizes of the

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/chart/pie.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/chart/pie.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/chart/pie.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/chart/pie.js Mon Feb  4 02:23:55 2013
@@ -23,10 +23,12 @@ App.ChartPieView = Em.View.extend({
   h:90,
   data:[300, 500],
   palette: new Rickshaw.Color.Palette({ scheme: 'munin'}),
+  stroke: 'black',
+  strokeWidth: 2,
   donut:d3.layout.pie().sort(null),
 
   r:function () {
-    return Math.min(this.get('w'), this.get('h')) / 2;
+    return Math.min(this.get('w'), this.get('h')) / 2 - this.get('strokeWidth');
   }.property('w', 'h'),
 
   outerR:function () {
@@ -56,6 +58,8 @@ App.ChartPieView = Em.View.extend({
     this.set('svg', d3.select(this.get('selector')).append("svg:svg")
       .attr("width", thisChart.get('w'))
       .attr("height", thisChart.get('h'))
+      .attr("stroke", this.get('stroke'))
+      .attr("stroke-width", this.get('strokeWidth'))
       .append("svg:g")
       .attr("transform", "translate(" + thisChart.get('w') / 2 + "," + thisChart.get('h') / 2 + ")"));
 

Added: incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/filter_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/filter_view.js?rev=1442010&view=auto
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/filter_view.js (added)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/filter_view.js Mon Feb  4 02:23:55 2013
@@ -0,0 +1,249 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Wrapper View for all filter components. Layout template and common actions are located inside of it.
+ * Logic specific for data component(input, select, or custom multi select, which fire any changes on interface) are
+ * located in inner view - <code>filterView</code>.
+ *
+ * If we want to have input filter, put <code>textFieldView</code> to it.
+ * All inner views implemented below this view.
+ * @type {*}
+ */
+var wrapperView = Ember.View.extend({
+  classNames: ['view-wrapper'],
+  layout: Ember.Handlebars.compile('<a href="#" {{action "clearFilter" target="view"}} class="ui-icon ui-icon-circle-close"></a> {{yield}}'),
+  template: Ember.Handlebars.compile('{{#if view.fieldId}}<input type="hidden" id="{{unbound view.fieldId}}" value="" />{{/if}} {{view view.filterView}}'),
+
+  value: null,
+
+  /**
+   * If this field is exists we dynamically create hidden input element and set value there.
+   * Used for some cases, where this values will be used outside of component
+   */
+  fieldId: null,
+
+  clearFilter: function(){
+    this.set('value', this.get('emptyValue'));
+    return false;
+  },
+
+  /**
+   * Use to determine whether filter is clear or not. Also when we want to set empty value
+   */
+  emptyValue: '',
+
+  /**
+   * Whether our <code>value</code> is empty or not
+   * @return {Boolean}
+   */
+  isEmpty: function(){
+    if(this.get('value') === null){
+      return true;
+    }
+    return this.get('value').toString() === this.get('emptyValue').toString();
+  },
+
+  /**
+   * Show/Hide <code>Clear filter</code> button.
+   * Also this method updates computed field related to <code>fieldId</code> if it exists.
+   * Call <code>onChangeValue</code> callback when everything is done.
+   */
+  showClearFilter: function(){
+    if(!this.get('parentNode')){
+      return;
+    }
+
+    if(this.isEmpty()){
+      this.get('parentNode').addClass('notActive');
+    } else {
+      this.get('parentNode').removeClass('notActive');
+    }
+
+    if(this.get('fieldId')){
+      this.$('> input').eq(0).val(this.get('value'));
+    }
+
+    this.onChangeValue();
+  }.observes('value'),
+
+  /**
+   * Callback for value changes
+   */
+  onChangeValue: function(){
+
+  },
+
+  /**
+   * Filter components is located here. Should be redefined
+   */
+  filterView: Em.View,
+
+  /**
+   * Update class of parentNode(hide clear filter button) on page load
+   */
+  didInsertElement: function(){
+    var parent = this.$().parent();
+    this.set('parentNode', parent);
+    parent.addClass('notActive');
+  }
+});
+
+/**
+ * Simple input control for wrapperView
+ */
+var textFieldView = Ember.TextField.extend({
+  type:'text',
+  placeholder: 'Any',
+  valueBinding: "parentView.value"
+});
+
+/**
+ * Simple multiselect control for wrapperView.
+ * Used to render blue button and popup, which opens on button click.
+ * All content related logic should be implemented manually outside of it
+ */
+var componentFieldView = Ember.View.extend({
+  classNames: ['btn-group'],
+  classNameBindings: ['isFilterOpen:open:'],
+
+  /**
+   * Whether popup is shown or not
+   */
+  isFilterOpen: false,
+
+  /**
+   * We have <code>value</code> property similar to inputs <code>value</code> property
+   */
+  valueBinding: 'parentView.value',
+
+  /**
+   * Clear filter to initial state
+   */
+  clearFilter: function(){
+    this.set('value', '');
+  },
+
+  /**
+   * Onclick handler for <code>cancel filter</code> button
+   */
+  closeFilter:function () {
+    $(document).unbind('click');
+    this.set('isFilterOpen', false);
+  },
+
+  /**
+   * Onclick handler for <code>apply filter</code> button
+   */
+  applyFilter:function() {
+    this.closeFilter();
+  },
+
+  /**
+   * Onclick handler for <code>show component filter</code> button.
+   * Also this function is used in some other places
+   */
+  clickFilterButton:function () {
+    var self = this;
+    this.set('isFilterOpen', !this.get('isFilterOpen'));
+    if (this.get('isFilterOpen')) {
+
+      var dropDown = this.$('.filter-components');
+      var firstClick = true;
+      $(document).bind('click', function (e) {
+        if (!firstClick && $(e.target).closest(dropDown).length == 0) {
+          self.set('isFilterOpen', false);
+          $(document).unbind('click');
+        }
+        firstClick = false;
+      });
+    }
+  }
+});
+
+/**
+ * Simple select control for wrapperView
+ */
+var selectFieldView = Ember.Select.extend({
+  selectionBinding: 'parentView.value',
+  contentBinding: 'parentView.content'
+});
+
+/**
+ * Result object, which will be accessible outside
+ * @type {Object}
+ */
+module.exports = {
+  /**
+   * You can access wrapperView outside
+   */
+  wrapperView : wrapperView,
+
+  /**
+   * And also controls views if need it
+   */
+  textFieldView : textFieldView,
+  selectFieldView: selectFieldView,
+  componentFieldView: componentFieldView,
+
+  /**
+   * Quick create input filters
+   * @param config parameters of <code>wrapperView</code>
+   */
+  createTextView : function(config){
+
+    config.fieldType = config.fieldType || 'input-medium';
+    config.filterView = textFieldView.extend({
+      classNames : [ config.fieldType ]
+    });
+
+    return wrapperView.extend(config);
+  },
+
+  /**
+   * Quick create multiSelect filters
+   * @param config parameters of <code>wrapperView</code>
+   */
+  createComponentView : function(config){
+    config.clearFilter = function(){
+      this.forEachChildView(function(item){
+        if(item.clearFilter){
+          item.clearFilter();
+        }
+      });
+      return false;
+    };
+
+    return wrapperView.extend(config);
+  },
+
+  /**
+   * Quick create select filters
+   * @param config parameters of <code>wrapperView</code>
+   */
+  createSelectView: function(config){
+
+    config.fieldType = config.fieldType || 'input-medium';
+    config.filterView = selectFieldView.extend({
+      classNames : [ config.fieldType ]
+    });
+    config.emptyValue = 'Any';
+
+    return wrapperView.extend(config);
+  }
+};
\ No newline at end of file

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/modal_popup.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/modal_popup.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/modal_popup.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/modal_popup.js Mon Feb  4 02:23:55 2013
@@ -23,7 +23,7 @@ App.ModalPopup = Ember.View.extend({
   template: Ember.Handlebars.compile([
     '<div class="modal-backdrop"></div><div class="modal" id="modal" tabindex="-1" role="dialog" aria-labelledby="modal-label" aria-hidden="true">',
     '<div class="modal-header">',
-    '<a class="close" {{action onClose target="view"}}>x</a>',
+    '{{#if showCloseButton}}<a class="close" {{action onClose target="view"}}>x</a>{{/if}}',
     '<h3 id="modal-label">',
     '{{#if headerClass}}{{view headerClass}}',
     '{{else}}{{header}}{{/if}}',
@@ -34,11 +34,15 @@ App.ModalPopup = Ember.View.extend({
     '{{else}}{{#if encodeBody}}{{body}}{{else}}{{{body}}}{{/if}}{{/if}}',
     '</div>',
     '{{#if showFooter}}',
+    '{{#if footerClass}}{{view footerClass}}',
+    '{{else}}',
     '<div class="modal-footer">',
     '{{#if view.secondary}}<a class="btn" {{action onSecondary target="view"}}>{{view.secondary}}</a>{{/if}}',
     '{{#if view.primary}}<a class="btn btn-success" {{action onPrimary target="view"}}>{{view.primary}}</a>{{/if}}',
     '</div>',
     '{{/if}}',
+    '{{/if}}',
+
     '</div>'
   ].join('\n')),
 
@@ -67,12 +71,31 @@ App.ModalPopup = Ember.View.extend({
 
   showFooter: true,
 
+  /**
+   * Hide or show 'X' button for closing popup
+   */
+  showCloseButton: true,
+
   didInsertElement: function(){
     if(this.autoHeight){
       this._super();
       var block = this.$().find('#modal > .modal-body').first();
-      block.css('max-height', $(window).height()- block.offset().top - 100); // fix popup height
+      block.css('max-height', $(window).height()- block.offset().top - 300); // fix popup height
     }
+  },
+
+  fitHeight: function(){
+    var popup = this.$().find('#modal');
+    var block = this.$().find('#modal > .modal-body');
+    var wh = $(window).height();
+
+    var top = wh * .05;
+    popup.css({
+      'top' : top + 'px',
+      'marginTop' : 0
+    });
+
+    block.css('max-height', $(window).height()- top * 2 - 100);
   }
 });
 
@@ -81,6 +104,7 @@ App.ModalPopup.reopenClass({
   show: function(options) {
     var popup = this.create(options);
     popup.appendTo('#wrapper');
+    return popup;
   }
 
 })

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/quick_view_link_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/quick_view_link_view.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/quick_view_link_view.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/common/quick_view_link_view.js Mon Feb  4 02:23:55 2013
@@ -25,15 +25,15 @@ App.QuickViewLinks = Em.View.extend({
    */
   quickLinks:function () {
     var serviceName = this.get('content.serviceName');
-    var components = this.get('content.components');
+    var components = this.get('content.hostComponents');
     var host;
 
     if (serviceName === 'HDFS') {
-      host = components.filterProperty('id', 'NAMENODE').objectAt(0).get('host.publicHostName');
+      host = components.findProperty('componentName', 'NAMENODE').get('host.publicHostName');
     } else if (serviceName === 'MAPREDUCE') {
-      host = components.filterProperty('id', 'JOBTRACKER').objectAt(0).get('host.publicHostName');
+      host = components.findProperty('componentName', 'JOBTRACKER').get('host.publicHostName');
     } else if (serviceName === 'HBASE') {
-      host = components.filterProperty('id', 'HBASE_MASTER').objectAt(0).get('host.publicHostName');
+      host = components.findProperty('componentName', 'HBASE_MASTER').get('host.publicHostName');
     }
     if (!host) {
       return [];

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/admin/user/create.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/admin/user/create.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/admin/user/create.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/admin/user/create.js Mon Feb  4 02:23:55 2013
@@ -25,25 +25,41 @@ App.MainAdminUserCreateView = Em.View.ex
     var parent_controller=this.get("controller").controllers.mainAdminUserController;
     var form = this.get("userForm");
     if(form.isValid()) {
-      form.getField("userName").set('value', form.getValues().userName.toLowerCase());
-      if(form.getValues().admin === "" || form.getValues().admin == true) {
+      form.getField("userName").set('value', form.getField("userName").get('value').toLowerCase());
+      if(form.getField("admin").get('value') === "" || form.getField("admin").get('value') == true) {
         form.getField("roles").set("value","admin,user");
         form.getField("admin").set("value","true");
       } else{
         form.getField("roles").set("value","user");
       }
-
-      parent_controller.sendCommandToServer('/users/' + form.getValues().userName, "POST" , {
+      parent_controller.sendCommandToServer('/users/' + form.getField("userName").get('value'), "POST" , {
         Users: {
-          password: form.getValues().password,
-          roles: form.getValues().roles
+          password: form.getField("password").get('value'),
+          roles: form.getField("roles").get('value')
         }
       }, function (success) {
 
         if (!success) {
+          App.ModalPopup.show({
+            header: Em.I18n.t('admin.users.addButton'),
+            body: Em.I18n.t('admin.users.createError'),
+            primary: 'Ok',
+            secondary: null,
+            onPrimary: function() {
+              this.hide();
+            }
+          });
           return;
         }
-
+        App.ModalPopup.show({
+          header: Em.I18n.t('admin.users.addButton'),
+          body: Em.I18n.t('admin.users.createSuccess'),
+          primary: 'Ok',
+          secondary: null,
+          onPrimary: function() {
+            this.hide();
+          }
+        });
         form.save();
 
         App.router.transitionTo("allUsers");

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/admin/user/edit.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/admin/user/edit.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/admin/user/edit.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/admin/user/edit.js Mon Feb  4 02:23:55 2013
@@ -26,25 +26,33 @@ App.MainAdminUserEditView = Em.View.exte
     var form = this.get("userForm");
     if(form.isValid()) {
       var Users={};
-      if(form.getValues().admin === "" || form.getValues().admin == true) {
+      if(form.getField("admin").get('value') === "" || form.getField("admin").get('value') == true) {
         form.getField("roles").set("value","admin,user");
-        form.getField("admin").set("value","true");
+        form.getField("admin").set("value", true);
       } else{
         form.getField("roles").set("value","user");
       }
 
-      Users.roles = form.getValues().roles;
+      Users.roles = form.getField("roles").get('value');
 
-      if(form.getValues().new_password != "" && form.getValues().old_password != ""){
-        Users.password=form.getValues().new_password;
-        Users.old_password=form.getValues().old_password;
+      if(form.getField("new_password").get('value') != "" && form.getField("old_password").get('value') != "") {
+        Users.password = form.getField("new_password").get('value');
+        Users.old_password = form.getField("old_password").get('value');
       }
 
-      parent_controller.sendCommandToServer('/users/' + form.getValues().userName, "PUT" , {
+      parent_controller.sendCommandToServer('/users/' + form.getField("userName").get('value'), "PUT" , {
        Users:Users
-      }, function (success) {
-
+      }, function (success, message) {
         if (!success) {
+          App.ModalPopup.show({
+            header: Em.I18n.t('admin.users.editButton'),
+            body: message,
+            primary: 'Ok',
+            secondary: null,
+            onPrimary: function() {
+              this.hide();
+            }
+          });
           return;
         }
 
@@ -57,14 +65,13 @@ App.MainAdminUserEditView = Em.View.exte
 
   userForm: App.EditUserForm.create({}),
 
-  didInsertElement: function(){
+  didInsertElement: function() {
     var form = this.get('userForm');
-    if( form.getField("isLdap").get("value") )
-    {
+    if(form.getField("isLdap").get("value")) {
       form.getField("old_password").set("disabled",true);
       form.getField("new_password").set("disabled",true);
-    }else{
-      //debugger;
+    }
+    else {
       form.getField("old_password").set("disabled",false);
       form.getField("new_password").set("disabled",false);
     }

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item/bar_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item/bar_view.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item/bar_view.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item/bar_view.js Mon Feb  4 02:23:55 2013
@@ -24,9 +24,18 @@ App.MainAppsItemBarView = Em.View.extend
   templateName:require('templates/main/apps/item/bar'),
   width:300,
   height:210,
-
+  /**
+   * Jobs list. Sorted by job id
+   */
   content:function () {
-    return this.get('controller.content.jobs');
+    return this.get('controller.content.jobs').sort(function(a, b) {
+      var jobIdA = a.get('id').toLowerCase(), jobIdB = b.get('id').toLowerCase();
+      if (jobIdA < jobIdB)
+        return -1;
+      if (jobIdA > jobIdB)
+        return 1;
+      return 0;
+    });
   }.property('controller.content.jobs'),
   firstJob:function () {
     return this.get('content').get('firstObject');
@@ -79,14 +88,22 @@ App.MainAppsItemBarView = Em.View.extend
       "&width=" + this.get('width');
     var mapper = App.jobTimeLineMapper;
     mapper.set('model', this);
-    App.HttpClient.get(url, mapper);
+    App.HttpClient.get(url, mapper,{
+      complete:function(jqXHR, textStatus) {
+        console.log("updateTimeLine");
+      }
+    });
   }.observes('getChartData'),
 
   updateTasksView:function () {
     var url = App.testMode ? '/data/apps/jobs/taskview.json' : App.apiPrefix + "/jobhistory/tasklocality?jobId=" + this.get('activeJob').get('id');
     var mapper = App.jobTasksMapper;
     mapper.set('model', this);
-    App.HttpClient.get(url, mapper);
+    App.HttpClient.get(url, mapper,{
+      complete:function(jqXHR, textStatus) {
+        console.log("updateTasksView");
+      }
+    });
   }.observes('getChartData'),
 
   drawJobTimeline:function () {
@@ -94,7 +111,7 @@ App.MainAppsItemBarView = Em.View.extend
     var shuffle = JSON.stringify(this.get('shuffle'));
     var reduce = JSON.stringify(this.get('reduce'));
     if (!this.get('map') || !this.get('shuffle') || !this.get('reduce')) {return;}
-    $('#chart, #legend, #timeline1').html('');
+    $('#chart, #legend, #timeline1, #y-axis').html('');
     graph.drawJobTimeLine(map, shuffle, reduce, this.get('width'), this.get('height'), '#chart', 'legend', 'timeline1');
   }.observes('map', 'shuffle', 'reduce'),
 
@@ -104,7 +121,7 @@ App.MainAppsItemBarView = Em.View.extend
     var mapOffSwitch = JSON.stringify(this.get('mapOffSwitch'));
     var reduceOffSwitch = JSON.stringify(this.get('reduceOffSwitch'));
     if (!this.get('mapNodeLocal') || !this.get('mapRackLocal') || !this.get('mapOffSwitch') || !this.get('reduceOffSwitch')) {return;}
-    $('#job_tasks, #tasks_legend, #timeline2').html('');
+    $('#job_tasks, #tasks_legend, #timeline2, #y-axis2').html('');
     graph.drawJobTasks(mapNodeLocal, mapRackLocal, mapOffSwitch, reduceOffSwitch, this.get('submit'), this.get('width'), this.get('height'), '#job_tasks', 'tasks_legend', 'timeline2');
   }.observes('mapNodeLocal', 'mapRackLocal', 'mapOffSwitch', 'reduceOffSwitch', 'submit')
 

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item/dag_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item/dag_view.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item/dag_view.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item/dag_view.js Mon Feb  4 02:23:55 2013
@@ -22,7 +22,12 @@ App.MainAppsItemDagView = Em.View.extend
   templateName: require('templates/main/apps/item/dag'),
   elementId : 'jobs',
   content:function(){
-    return this.get('controller.content.jobs');
+    //if(this.get("controller.jobsLoaded") == true)
+   // {
+      return this.get('controller.content.jobs');
+  //  }
+      return this.get('controller.content.jobs');
+  //  }
   }.property('controller.content.jobs'),
 
   classNames:['table','dataTable'],
@@ -35,11 +40,13 @@ App.MainAppsItemDagView = Em.View.extend
     c.forEach(function(item, index){
       result[index] = new Object({
         'name' : item.get('id'),
-        'entityName' : item.get('workflowEntityName'),
+        'entityName' : item.get('workflow_entity_name'),
         'status' : item.get('status') == 'SUCCESS',
         'info' : [],
-        'input' : item.get('inputBytes'),
-        'output' : item.get('outputBytes')
+        'input' : item.get('input'),
+        'output' : item.get('output'),
+        'submitTime' : item.get('submit_time'),
+        'elapsedTime' : item.get('elapsed_time')
       })
     });
     return result;
@@ -62,6 +69,29 @@ App.MainAppsItemDagView = Em.View.extend
 
   }.observes('controller.content.loadAllJobs'),
 
+  resizeModal: function () {
+    var modal = $('.modal');
+    var body = $('body');
+    modal.find('.modal-body').first().css('max-height', 'none');
+    var modalHeight = modal.height() + 300;
+    var bodyHeight = body.height();
+    if (modalHeight > bodyHeight) {
+      modal.css('top', '20px');
+      $('.modal-body').height(bodyHeight - 180);
+    } else {
+      modal.css('top', (bodyHeight - modalHeight) / 2 + 'px');
+    }
+
+    var modalWidth = modal.width();
+    var bodyWidth = body.width();
+    if (modalWidth > bodyWidth) {
+      modal.css('left', '10px');
+      modal.width(bodyWidth - 20);
+    } else {
+      modal.css('left', (bodyWidth - modalWidth) / 2 + 'px');
+    }
+  },
+
   didInsertElement: function(){
     this.onLoad();
   },
@@ -101,9 +131,9 @@ App.MainAppsItemDagView = Em.View.extend
     innerTable.fnSettings().oFeatures.bFilter = false;
     var dagSchema = this.get('controller.content.workflowContext');
     var jobs = this.get('jobs');
-    var graph = new DagViewer(false, 'dag_viewer')
-        .setPhysicalParametrs(this.$().width(), 300, -800, 0.01)
+    this.resizeModal();
+    var graph = new DagViewer('dag_viewer')
         .setData(dagSchema, jobs)
-        .drawDag(10, 20, 100);
+        .drawDag(this.$().width(), 300, 20);
   }
 });

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item_view.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item_view.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps/item_view.js Mon Feb  4 02:23:55 2013
@@ -24,12 +24,12 @@ App.MainAppsItemView = Em.View.extend({
   templateName:require('templates/main/apps/item'),
   menuTabs:[
     Em.Object.create({
-      label:'DAG',
+      label:Em.I18n.t('apps.dagCharts.popup.dag'),
       active:'active',
       content:'App.MainAppsItemDagView'
     }),
     Em.Object.create({
-      label:'Charts',
+      label:Em.I18n.t('apps.dagCharts.popup.tasks'),
       active:'',
       content:'App.MainAppsItemBarView'
     })