You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by su...@apache.org on 2016/10/04 15:19:53 UTC

[22/50] [abbrv] hadoop git commit: YARN-5321. [YARN-3368] Add resource usage for application by node managers (Wangda Tan via Sunil G) YARN-5320. [YARN-3368] Add resource usage by applications and queues to cluster overview page (Wangda Tan via Sunil G)

YARN-5321. [YARN-3368] Add resource usage for application by node managers (Wangda Tan via Sunil G)
YARN-5320. [YARN-3368] Add resource usage by applications and queues to cluster overview page  (Wangda Tan via Sunil G)
YARN-5322. [YARN-3368] Add a node heat chart map (Wangda Tan via Sunil G)
YARN-5347. [YARN-3368] Applications page improvements (Sreenath Somarajapuram via Sunil G)
YARN-5348. [YARN-3368] Node details page improvements (Sreenath Somarajapuram via Sunil G)
YARN-5346. [YARN-3368] Queues page improvements (Sreenath Somarajapuram via Sunil G)
YARN-5345. [YARN-3368] Cluster overview page improvements (Sreenath Somarajapuram via Sunil G)
YARN-5344. [YARN-3368] Generic UI improvements (Sreenath Somarajapuram via Sunil G)


Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/53874603
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/53874603
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/53874603

Branch: refs/heads/YARN-3368
Commit: 5387460330265c1d81a91e7ea789b10a42f2d292
Parents: 597b8a7
Author: Sunil <su...@apache.org>
Authored: Fri Jul 15 21:16:06 2016 +0530
Committer: sunilg <su...@apache.org>
Committed: Tue Oct 4 20:48:08 2016 +0530

----------------------------------------------------------------------
 .../src/main/webapp/app/adapters/yarn-app.js    |  14 +
 .../app/components/app-usage-donut-chart.js     |  67 ++++
 .../src/main/webapp/app/components/bar-chart.js |   5 +
 .../app/components/base-chart-component.js      |  55 ++-
 .../app/components/base-usage-donut-chart.js    |  43 +++
 .../main/webapp/app/components/donut-chart.js   |  55 ++-
 .../main/webapp/app/components/nodes-heatmap.js | 209 +++++++++++
 ...er-app-memusage-by-nodes-stacked-barchart.js |  88 +++++
 ...app-ncontainers-by-nodes-stacked-barchart.js |  67 ++++
 .../app/components/queue-usage-donut-chart.js   |  69 ++++
 .../main/webapp/app/components/queue-view.js    |   3 +-
 .../main/webapp/app/components/simple-table.js  |   9 +-
 .../webapp/app/components/stacked-barchart.js   | 198 +++++++++++
 .../main/webapp/app/components/timeline-view.js |   2 +-
 .../main/webapp/app/components/tree-selector.js |  43 ++-
 .../webapp/app/controllers/cluster-overview.js  |   9 +
 .../webapp/app/controllers/yarn-app-attempt.js  |  40 +++
 .../webapp/app/controllers/yarn-app-attempts.js |  40 +++
 .../src/main/webapp/app/controllers/yarn-app.js |  38 ++
 .../main/webapp/app/controllers/yarn-apps.js    |   9 +
 .../webapp/app/controllers/yarn-node-apps.js    |  39 +++
 .../app/controllers/yarn-node-containers.js     |  39 +++
 .../main/webapp/app/controllers/yarn-node.js    |  37 ++
 .../app/controllers/yarn-nodes-heatmap.js       |  36 ++
 .../main/webapp/app/controllers/yarn-nodes.js   |  33 ++
 .../webapp/app/controllers/yarn-queue-apps.js   |  46 +++
 .../main/webapp/app/controllers/yarn-queue.js   |  20 ++
 .../main/webapp/app/controllers/yarn-queues.js  |  34 ++
 .../webapp/app/controllers/yarn-services.js     |  34 ++
 .../main/webapp/app/models/cluster-metric.js    |   2 +-
 .../main/webapp/app/models/yarn-app-attempt.js  |  11 +
 .../src/main/webapp/app/models/yarn-app.js      |   4 +
 .../src/main/webapp/app/models/yarn-rm-node.js  |   7 +
 .../src/main/webapp/app/router.js               |  15 +-
 .../src/main/webapp/app/routes/application.js   |   2 +
 .../main/webapp/app/routes/cluster-overview.js  |   9 +-
 .../main/webapp/app/routes/yarn-app-attempts.js |  30 ++
 .../src/main/webapp/app/routes/yarn-app.js      |  17 +-
 .../src/main/webapp/app/routes/yarn-apps.js     |   6 +-
 .../main/webapp/app/routes/yarn-apps/apps.js    |  22 ++
 .../webapp/app/routes/yarn-apps/services.js     |  22 ++
 .../src/main/webapp/app/routes/yarn-node.js     |   1 +
 .../src/main/webapp/app/routes/yarn-nodes.js    |   5 +-
 .../webapp/app/routes/yarn-nodes/heatmap.js     |  22 ++
 .../main/webapp/app/routes/yarn-nodes/table.js  |  22 ++
 .../main/webapp/app/routes/yarn-queue-apps.js   |  36 ++
 .../src/main/webapp/app/routes/yarn-queues.js   |  38 ++
 .../webapp/app/serializers/yarn-app-attempt.js  |  19 +-
 .../src/main/webapp/app/serializers/yarn-app.js |   8 +-
 .../webapp/app/serializers/yarn-container.js    |  20 +-
 .../src/main/webapp/app/styles/app.css          | 139 ++++++--
 .../main/webapp/app/templates/application.hbs   |  99 ++++--
 .../webapp/app/templates/cluster-overview.hbs   | 168 ++++++---
 .../app/templates/components/app-table.hbs      |  10 +-
 .../templates/components/node-menu-panel.hbs    |   2 +-
 .../app/templates/components/nodes-heatmap.hbs  |  27 ++
 .../components/queue-configuration-table.hbs    |   4 -
 .../templates/components/queue-navigator.hbs    |  14 +-
 .../app/templates/components/timeline-view.hbs  |   3 +-
 .../webapp/app/templates/yarn-app-attempt.hbs   |  13 +-
 .../webapp/app/templates/yarn-app-attempts.hbs  |  57 +++
 .../src/main/webapp/app/templates/yarn-app.hbs  | 346 ++++++++++++-------
 .../src/main/webapp/app/templates/yarn-apps.hbs |  82 ++++-
 .../webapp/app/templates/yarn-apps/apps.hbs     |  24 ++
 .../webapp/app/templates/yarn-apps/services.hbs |  27 ++
 .../webapp/app/templates/yarn-node-apps.hbs     |   4 +
 .../app/templates/yarn-node-container.hbs       |   4 +
 .../app/templates/yarn-node-containers.hbs      |   4 +
 .../src/main/webapp/app/templates/yarn-node.hbs | 148 ++++----
 .../main/webapp/app/templates/yarn-nodes.hbs    |  99 +++---
 .../webapp/app/templates/yarn-nodes/heatmap.hbs |  30 ++
 .../webapp/app/templates/yarn-nodes/table.hbs   |  67 ++++
 .../webapp/app/templates/yarn-queue-apps.hbs    |  66 ++++
 .../main/webapp/app/templates/yarn-queue.hbs    | 126 ++++---
 .../main/webapp/app/templates/yarn-queues.hbs   |  72 ++++
 .../src/main/webapp/app/utils/color-utils.js    |  67 ++++
 .../src/main/webapp/app/utils/converter.js      |  17 +
 .../main/webapp/app/utils/href-address-utils.js |  29 ++
 .../src/main/webapp/app/utils/mock.js           |  36 ++
 .../hadoop-yarn-ui/src/main/webapp/bower.json   |   3 +-
 .../hadoop-yarn-ui/src/main/webapp/package.json |   4 +
 .../unit/controllers/yarn-app-attempt-test.js   |  30 ++
 .../unit/controllers/yarn-app-attempts-test.js  |  30 ++
 .../tests/unit/controllers/yarn-app-test.js     |  30 ++
 .../unit/controllers/yarn-node-apps-test.js     |  30 ++
 .../controllers/yarn-node-containers-test.js    |  30 ++
 .../tests/unit/controllers/yarn-node-test.js    |  30 ++
 .../unit/controllers/yarn-nodes-heatmap-test.js |  30 ++
 .../tests/unit/controllers/yarn-nodes-test.js   |  30 ++
 .../unit/controllers/yarn-queue-apps-test.js    |  30 ++
 .../tests/unit/controllers/yarn-queues-test.js  |   4 +-
 .../unit/controllers/yarn-services-test.js      |  30 ++
 .../tests/unit/routes/yarn-app-attempts-test.js |  29 ++
 .../tests/unit/routes/yarn-queue-apps-test.js   |  29 ++
 .../tests/unit/routes/yarn-queues-test.js       |  29 ++
 95 files changed, 3399 insertions(+), 482 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js
index afd93f4..67a2847 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js
@@ -23,6 +23,20 @@ export default AbstractAdapter.extend({
   restNameSpace: "cluster",
   serverName: "RM",
 
+  urlForQuery(query, modelName) {
+    var url = this._buildURL();
+    if (query.state) {
+      url = url + '/apps/?state=' + query.state;
+    }
+    return url;
+  },
+
+  urlForFindRecord(id, modelName, snapshot) {
+    var url = this._buildURL();
+    url = url + '/apps/' + id;
+    return url;
+  },
+
   pathForType(modelName) {
     return 'apps'; // move to some common place, return path by modelname.
   },

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js
new file mode 100644
index 0000000..0baf630
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js
@@ -0,0 +1,67 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import DonutChart from 'yarn-ui/components/donut-chart';
+import BaseUsageDonutChart from 'yarn-ui/components/base-usage-donut-chart';
+import ColorUtils from 'yarn-ui/utils/color-utils';
+import HrefAddressUtils from 'yarn-ui/utils/href-address-utils';
+
+export default BaseUsageDonutChart.extend({
+  colors: d3.scale.category20().range(),
+
+  draw: function() {
+    this.initChart();
+    var usageByApps = [];
+    var avail = 100;
+
+    this.get("data").forEach(function (app) {
+      var v = app.get("clusterUsagePercentage");
+      if (v > 1e-2) {
+        usageByApps.push({
+          label: app.get("id"),
+          link: HrefAddressUtils.getApplicationLink(app.get("id")),
+          value: v.toFixed(2)
+        });
+
+        console.log(v);
+        avail = avail - v;
+      }
+    }.bind(this));
+
+    usageByApps.sort(function(a,b) {
+      return b.value - a.value;
+    });
+
+    usageByApps = this.mergeLongTails(usageByApps, 8);
+
+    usageByApps.push({
+      label: "Available",
+      value: avail.toFixed(4)
+    })
+
+    this.colors = ColorUtils.getColors(usageByApps.length, ["others", "good"], true);
+
+    this.renderDonutChart(usageByApps, this.get("title"), this.get("showLabels"),
+      this.get("middleLabel"), "100%", "%");
+  },
+
+  didInsertElement: function() {
+    this.draw();
+  },
+})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js
index 8e48279..7bb292f 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js
@@ -116,6 +116,11 @@ export default BaseChartComponent.extend({
     this.renderBarChart(this.get("data"), this.get("title"), this.get("textWidth"));
   },
 
+  _dataChange: Ember.observer("data", function() {
+    this.chart.g.selectAll("*").remove();
+    this.renderBarChart(this.get("data"), this.get("title"), this.get("textWidth"));
+  }),
+
   didInsertElement: function() {
     this.draw();
   },

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js
index b85b6ab4..d221488 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js
@@ -17,23 +17,26 @@
  */
 
 import Ember from 'ember';
+import Converter from 'yarn-ui/utils/converter';
 
 export default Ember.Component.extend({
-  chart: undefined,
   tooltip : undefined,
   colors: d3.scale.category10().range(),
 
-  initChart: function() {
-    this.chart = {
+  init: function () {
+    this._super();
+    this.set("chart", {
       svg: undefined,
       g: undefined,
       h: 0,
       w: 0,
       tooltip: undefined
-    };
+    });
+  },
 
+  initChart: function(removeLast = false) {
     // Init tooltip if it is not initialized
-    this.tooltip = d3.select("#chart-tooltip");
+    // this.tooltip = d3.select("#chart-tooltip");
     if (!this.tooltip) {
       this.tooltip = d3.select("body")
         .append("div")
@@ -42,13 +45,16 @@ export default Ember.Component.extend({
         .style("opacity", 0);
     }
 
-    // Init svg
-    var svg = this.chart.svg;
-    if (svg) {
-      svg.remove();
+    var parentId = this.get("parentId");
+
+    if (removeLast) {
+      // Init svg
+      var svg = d3.select("#" + parentId + "-svg");
+      if (svg) {
+        svg.remove();
+      }
     }
 
-    var parentId = this.get("parentId");
     var parent = d3.select("#" + parentId);
     var bbox = parent.node().getBoundingClientRect();
     this.chart.w = bbox.width - 30;
@@ -65,12 +71,13 @@ export default Ember.Component.extend({
 
     this.chart.svg = parent.append("svg")
       .attr("width", this.chart.w)
-      .attr("height", this.chart.h);
+      .attr("height", this.chart.h)
+      .attr("id", parentId + "-svg");
 
     this.chart.g = this.chart.svg.append("g");
   },
 
-  renderTitleAndBG: function(g, title, layout) {
+  renderTitleAndBG: function(g, title, layout, background=true) {
     var bg = g.append("g");
     bg.append("text")
       .text(title)
@@ -78,12 +85,14 @@ export default Ember.Component.extend({
       .attr("y", layout.y1 + layout.margin + 20)
       .attr("class", "chart-title");
 
-    bg.append("rect")
-      .attr("x", layout.x1)
-      .attr("y", layout.y1)
-      .attr("width", layout.x2 - layout.x1)
-      .attr("height", layout.y2 - layout.y1)
-      .attr("class", "chart-frame");
+    if (background) {
+      bg.append("rect")
+        .attr("x", layout.x1)
+        .attr("y", layout.y1)
+        .attr("width", layout.x2 - layout.x1)
+        .attr("height", layout.y2 - layout.y1)
+        .attr("class", "chart-frame");
+    }
   },
 
   bindTooltip: function(d) {
@@ -100,7 +109,11 @@ export default Ember.Component.extend({
         }
 
         this.tooltip.style("opacity", .9);
-        this.tooltip.html(data.label + " = " + data.value)
+        var value = data.value;
+        if (this.get("type") == "memory") {
+          value = Converter.memoryToSimpliedUnit(value);
+        }
+        this.tooltip.html(data.label + " = " + value)
           .style("left", (d3.event.pageX) + "px")
           .style("top", (d3.event.pageY - 28) + "px");
       }.bind(this))
@@ -109,6 +122,10 @@ export default Ember.Component.extend({
       }.bind(this));
   },
 
+  adjustMaxHeight: function(h) {
+    this.chart.svg.attr("height", h);
+  },
+
   getLayout: function() {
     var x1 = 0;
     var y1 = 0;

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js
new file mode 100644
index 0000000..bec06c9
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js
@@ -0,0 +1,43 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import DonutChart from 'yarn-ui/components/donut-chart';
+
+export default DonutChart.extend({
+  mergeLongTails: function(usages, nItemsKept) {
+    var arr = [];
+    for (var i = 0; i < Math.min(usages.length, nItemsKept); i++) {
+      arr.push(usages[i]);
+    }
+
+    var others = {
+      label: "Used by others",
+      value: 0
+    }
+
+    for (var i = nItemsKept; i < usages.length; i++) {
+      others.value += Number(usages[i].value);
+    }
+    others.value = others.value.toFixed(2);
+
+    arr.push(others)
+
+    return arr;
+  },
+})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js
index e6dcb12..9a90855 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js
@@ -18,13 +18,15 @@
 
 import Ember from 'ember';
 import BaseChartComponent from 'yarn-ui/components/base-chart-component';
+import ColorUtils from 'yarn-ui/utils/color-utils';
+import Converter from 'yarn-ui/utils/converter';
 
 export default BaseChartComponent.extend({
   /*
    * data = [{label="xx", value=},{...}]
    */
   renderDonutChart: function(data, title, showLabels = false, 
-    middleLabel = "Total", middleValue = undefined) {
+    middleLabel = "Total", middleValue = undefined, suffix = "") {
     var g = this.chart.g;
     var layout = this.getLayout();
     this.renderTitleAndBG(g, title, layout);
@@ -39,7 +41,11 @@ export default BaseChartComponent.extend({
     }
 
     if (!middleValue) {
-      middleValue = total;
+      if (this.get("type") == "memory") {
+        middleValue = Converter.memoryToSimpliedUnit(total);
+      } else {
+        middleValue = total;
+      }
     }
 
     //Width and height
@@ -48,6 +54,8 @@ export default BaseChartComponent.extend({
     // 50 is for title
     var outerRadius = (h - 50 - 2 * layout.margin) / 2;
     var innerRadius = outerRadius * 0.618;
+    console.log("inner:" + innerRadius + " outer:" + outerRadius);
+
     var arc = d3.svg.arc()
       .innerRadius(innerRadius)
       .outerRadius(outerRadius);
@@ -104,12 +112,14 @@ export default BaseChartComponent.extend({
           return this.colors[i];
         }
       }.bind(this))
-      .attr("stroke-dasharray", function(d, i) {
-        if (d.value <= 1e-6) {
-          return "10,10";
-        }
-      }.bind(this));
     this.bindTooltip(path);
+    path.on("click", function (d) {
+      var data = d.data;
+      if (data.link) {
+        this.tooltip.remove();
+        document.location.href = data.link;
+      }
+    }.bind(this))
 
     // Show labels
     if (showLabels) {
@@ -126,27 +136,30 @@ export default BaseChartComponent.extend({
         }.bind(this))
         .attr("x", lx)
         .attr("y", function(d, i) {
-          return layout.y1 + 50 + (squareW + margin) * i + layout.margin;
+          return layout.y1 + 75 + (squareW + margin) * i + layout.margin;
         })
         .attr("width", squareW)
         .attr("height", squareW);
       select.append("text")
         .attr("x", lx + squareW + margin)
         .attr("y", function(d, i) {
-          return layout.y1 + 50 + (squareW + margin) * i + layout.margin + squareW / 2;
+          return layout.y1 + 80 + (squareW + margin) * i + layout.margin + squareW / 2;
         })
         .text(function(d) {
-          return d.label + ' = ' + d.value;
-        });
+          var value = d.value;
+          if (this.get("type") == "memory") {
+            value = Converter.memoryToSimpliedUnit(value);
+          }
+          return d.label + ' = ' + value + suffix;
+        }.bind(this));
     }
 
     if (middleLabel) {
       var highLightColor = this.colors[0];
       g.append("text").text(middleLabel).attr("x", cx).attr("y", cy - 10).
         attr("class", "donut-highlight-text").attr("fill", highLightColor);
-      g.append("text").text(middleValue).attr("x", cx).attr("y", cy + 20).
-        attr("class", "donut-highlight-text").attr("fill", highLightColor).
-        style("font-size", "30px");
+      g.append("text").text(middleValue).attr("x", cx).attr("y", cy + 15).
+        attr("class", "donut-highlight-sub").attr("fill", highLightColor);
     }
 
     path.transition()
@@ -154,8 +167,22 @@ export default BaseChartComponent.extend({
       .attrTween('d', tweenPie);
   },
 
+  _dataChange: Ember.observer("data", function() {
+    this.chart.g.selectAll("*").remove();
+    this.renderDonutChart(this.get("data"), this.get("title"), this.get("showLabels"),
+                          this.get("middleLabel"), this.get("middleValue"));
+  }),
+
   draw: function() {
     this.initChart();
+
+    var colorTargets = this.get("colorTargets");
+    if (colorTargets) {
+      var colorTargetReverse = Boolean(this.get("colorTargetReverse"));
+      var targets = colorTargets.split(" ");
+      this.colors = ColorUtils.getColors(this.get("data").length, targets, colorTargetReverse);
+    }
+
     this.renderDonutChart(this.get("data"), this.get("title"), this.get("showLabels"), 
                           this.get("middleLabel"), this.get("middleValue"));
   },

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js
new file mode 100644
index 0000000..af8ceb3
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js
@@ -0,0 +1,209 @@
+/**
+ * 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.
+ */
+
+import BaseChartComponent from 'yarn-ui/components/base-chart-component';
+import Mock from 'yarn-ui/utils/mock';
+
+export default BaseChartComponent.extend({
+  CELL_WIDTH: 250,
+  SAMPLE_CELL_WIDTH: 100,
+  SAMPLE_HEIGHT: 30,
+  CELL_HEIGHT: 30,
+  CELL_MARGIN: 2,
+  RACK_MARGIN: 20,
+  filter: "",
+
+  bindTP: function(element) {
+    element.on("mouseover", function() {
+      this.tooltip
+        .style("left", (d3.event.pageX) + "px")
+        .style("top", (d3.event.pageY - 28) + "px");
+      element.style("opacity", 1.0);
+    }.bind(this))
+      .on("mousemove", function() {
+        // Handle pie chart case
+        var text = element.attr("tooltiptext");
+
+        this.tooltip.style("opacity", .9);
+        this.tooltip.html(text)
+          .style("left", (d3.event.pageX) + "px")
+          .style("top", (d3.event.pageY - 28) + "px");
+      }.bind(this))
+      .on("mouseout", function() {
+        this.tooltip.style("opacity", 0);
+        element.style("opacity", 0.8);
+      }.bind(this));
+  },
+
+  // data:
+  //    [{label=label1, value=value1}, ...]
+  //    ...
+  renderCells: function (model, title) {
+    var data = [];
+    model.forEach(function (o) {
+      data.push(o);
+    });
+
+    this.chart.g.remove();
+    this.chart.g = this.chart.svg.append("g");
+    var g = this.chart.g;
+    var layout = this.getLayout();
+    layout.margin = 50;
+
+    let racks = new Set();
+    for (var i = 0; i < data.length; i++) {
+      racks.add(data[i].get("rack"));
+    }
+
+    let racksArray = [];
+    racks.forEach(v => racksArray.push(v));
+
+    var xOffset = layout.margin;
+    var yOffset = layout.margin * 3;
+
+    var colorFunc = d3.interpolate(d3.rgb("#bdddf5"), d3.rgb("#0f3957"));
+
+    var sampleXOffset = (layout.x2 - layout.x1) / 2 - 2.5 * this.SAMPLE_CELL_WIDTH -
+      2 * this.CELL_MARGIN;
+    var sampleYOffset = layout.margin * 2;
+
+    for (var i = 1; i <= 5; i++) {
+      var ratio = i * 0.2 - 0.1;
+
+      var rect = g.append("rect")
+        .attr("x", sampleXOffset)
+        .attr("y", sampleYOffset)
+        .attr("fill", colorFunc(ratio))
+        .attr("width", this.SAMPLE_CELL_WIDTH)
+        .attr("height", this.SAMPLE_HEIGHT);
+      g.append("text")
+        .text("" + (ratio * 100).toFixed(1) + "% Used")
+        .attr("y", sampleYOffset + this.SAMPLE_HEIGHT / 2 + 5)
+        .attr("x", sampleXOffset + this.SAMPLE_CELL_WIDTH / 2)
+        .attr("class", "heatmap-cell");
+      sampleXOffset += this.CELL_MARGIN + this.SAMPLE_CELL_WIDTH;
+    }
+
+    var chartXOffset = -1;
+
+    for (var i = 0; i < racksArray.length; i++) {
+      var text = g.append("text")
+        .text(racksArray[i])
+        .attr("y", yOffset + this.CELL_HEIGHT / 2 + 5)
+        .attr("x", layout.margin)
+        .attr("class", "heatmap-rack");
+
+      if (-1 == chartXOffset) {
+        chartXOffset = layout.margin + text.node().getComputedTextLength() + 30;
+      }
+
+      xOffset = chartXOffset;
+
+      for (var j = 0; j < data.length; j++) {
+        var rack = data[j].get("rack");
+        var host = data[j].get("nodeHostName");
+
+        if (rack == racksArray[i]) {
+          if (!rack.includes(this.filter) && !host.includes(this.filter)) {
+            this.addNode(g, xOffset, yOffset, colorFunc, data[j], false);
+            var text = g.append("text")
+              .text(host)
+              .attr("y", yOffset + this.CELL_HEIGHT / 2 + 5)
+              .attr("x", xOffset + this.CELL_WIDTH / 2)
+              .attr("class", "heatmap-cell-notselected");
+          } else {
+            this.addNode(g, xOffset, yOffset, colorFunc, data[j], true);
+            g.append("text")
+              .text(host)
+              .attr("y", yOffset + this.CELL_HEIGHT / 2 + 5)
+              .attr("x", xOffset + this.CELL_WIDTH / 2)
+              .attr("class", "heatmap-cell");
+          }
+
+          xOffset += this.CELL_MARGIN + this.CELL_WIDTH;
+          if (xOffset + this.CELL_MARGIN + this.CELL_WIDTH >= layout.x2 -
+            layout.margin) {
+            xOffset = chartXOffset;
+            yOffset = yOffset + this.CELL_MARGIN + this.CELL_HEIGHT;
+          }
+
+        }
+      }
+
+      while (xOffset > chartXOffset && xOffset + this.CELL_MARGIN +
+        this.CELL_WIDTH < layout.x2 - layout.margin) {
+        this.addPlaceholderNode(g, xOffset, yOffset);
+        xOffset += this.CELL_MARGIN + this.CELL_WIDTH;
+      }
+
+      if (xOffset != chartXOffset) {
+        xOffset = chartXOffset;
+        yOffset += this.CELL_MARGIN + this.CELL_HEIGHT;
+      }
+      yOffset += this.RACK_MARGIN;
+    }
+
+    layout.y2 = yOffset + layout.margin;
+    this.adjustMaxHeight(layout.y2);
+    this.renderTitleAndBG(g, title, layout, false);
+  },
+
+  addNode: function (g, xOffset, yOffset, colorFunc, data, selected) {
+    var rect = g.append("rect")
+      .attr("y", yOffset)
+      .attr("x", xOffset)
+      .attr("height", this.CELL_HEIGHT)
+      .attr("fill", colorFunc(data.get("usedMemoryMB") /
+        (data.get("usedMemoryMB") + data.get("availMemoryMB"))))
+      .attr("width", this.CELL_WIDTH)
+      .attr("tooltiptext", data.get("toolTipText"));
+    if (selected) {
+      rect.style("opacity", 0.8);
+      this.bindTP(rect);
+    } else {
+      rect.style("opacity", 0.8);
+      rect.attr("fill", "DimGray");
+    }
+  },
+
+  addPlaceholderNode: function(g, xOffset, yOffset) {
+    var rect = g.append("rect")
+      .attr("y", yOffset)
+      .attr("x", xOffset)
+      .attr("height", this.CELL_HEIGHT)
+      .attr("fill", "grey")
+      .attr("width", this.CELL_WIDTH)
+      .style("opacity", 0.20);
+  },
+
+  draw: function() {
+    this.initChart(true);
+    this.renderCells(this.get("model"), this.get("title"), this.get("textWidth"));
+  },
+
+  didInsertElement: function () {
+    this.draw();
+  },
+
+  actions: {
+    applyFilter: function(event) {
+      this.filter = event.srcElement.value;
+      this.didInsertElement();
+    }
+  }
+})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js
new file mode 100644
index 0000000..7feb7bb
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js
@@ -0,0 +1,88 @@
+/**
+ * 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.
+ */
+
+import StackedBarchart from 'yarn-ui/components/stacked-barchart';
+import Converter from 'yarn-ui/utils/converter';
+
+export default StackedBarchart.extend({
+  getDataForRender: function(containers, nodes) {
+    var arr = [];
+    var nodeToResources = {};
+    nodes.forEach(function(n) {
+      nodeToResources[n.id] =
+      {
+        used: Number(n.get("usedMemoryMB")),
+        avail: Number(n.get("availMemoryMB"))
+      }
+    });
+
+    containers.forEach(function(c) {
+      res = nodeToResources[c.get("assignedNodeId")];
+      if (res) {
+        if (!res.usedByTheApp) {
+          res.usedByTheApp = 0;
+        }
+        res.usedByTheApp += Number(c.get("allocatedMB"));
+      }
+    });
+
+    for (var nodeId in nodeToResources) {
+      var res = nodeToResources[nodeId];
+
+      var subArr = [];
+      var value = res.usedByTheApp ? res.usedByTheApp : 0;
+      subArr.push({
+        value: value,
+        bindText: "This app uses " + Converter.memoryToSimpliedUnit(value) + ". On node=" + nodeId,
+      });
+
+      value = res.used - value;
+      value = Math.max(value, 0);
+      subArr.push({
+        value: value,
+        bindText: "Other applications uses " + Converter.memoryToSimpliedUnit(value) + ". On node=" + nodeId,
+      });
+
+      subArr.push({
+        value: res.avail,
+        bindText: "Free resource " + Converter.memoryToSimpliedUnit(res.avail) + " . On node=" + nodeId
+      });
+
+      arr.push(subArr);
+    }
+
+    console.log(arr);
+
+    return arr;
+  },
+
+  didInsertElement: function() {
+    this.initChart(true);
+
+    this.colors = ["Orange", "Grey", "LimeGreen"];
+
+    var containers = this.get("rmContainers");
+    var nodes = this.get("nodes");
+
+    var data = this.getDataForRender(containers, nodes);
+
+    this.show(
+      data, this.get("title"), ["Used by this app", "Used by other apps",
+        "Available"]);
+  },
+})

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js
new file mode 100644
index 0000000..251f557
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js
@@ -0,0 +1,67 @@
+/**
+ * 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.
+ */
+
+import StackedBarchart from 'yarn-ui/components/stacked-barchart';
+
+export default StackedBarchart.extend({
+  getDataForRender: function(containers, nodes) {
+    var arr = [];
+    var nodeToContainers = {};
+    nodes.forEach(function(n) {
+      nodeToContainers[n.id] = 0;
+    });
+
+    containers.forEach(function(c) {
+      var nodeId = c.get("assignedNodeId");
+      var n = nodeToContainers[nodeId];
+      if (undefined != n) {
+        nodeToContainers[nodeId] += 1;
+      }
+    });
+
+    for (var nodeId in nodeToContainers) {
+      var n = nodeToContainers[nodeId];
+
+      var subArr = [];
+      subArr.push({
+        value: n,
+        bindText: "This app has " + n + " containers running on node=" + nodeId
+      });
+
+      arr.push(subArr);
+    }
+
+    console.log(arr);
+
+    return arr;
+  },
+
+  didInsertElement: function() {
+    this.initChart(true);
+
+    this.colors = ["Orange", "Grey", "Gainsboro"];
+
+    var containers = this.get("rmContainers");
+    var nodes = this.get("nodes");
+
+    var data = this.getDataForRender(containers, nodes);
+
+    this.show(
+      data, this.get("title"), ["Running containers from this app"]);
+  },
+})

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js
new file mode 100644
index 0000000..3532726
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js
@@ -0,0 +1,69 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import DonutChart from 'yarn-ui/components/donut-chart';
+import BaseUsageDonutChart from 'yarn-ui/components/base-usage-donut-chart';
+import ColorUtils from 'yarn-ui/utils/color-utils';
+import HrefAddressUtils from 'yarn-ui/utils/href-address-utils';
+
+export default BaseUsageDonutChart.extend({
+  colors: d3.scale.category20().range(),
+
+  draw: function() {
+    this.initChart();
+    var usageByQueues = [];
+    var avail = 100;
+
+    this.get("data").forEach(function (queue) {
+      var v = queue.get("absUsedCapacity");
+
+      if (queue.get("isLeafQueue")) {
+        if (v > 1e-2) {
+          usageByQueues.push({
+            label: queue.get("id"),
+            link: HrefAddressUtils.getQueueLink(queue.get("id")),
+            value: v.toFixed(2)
+          });
+
+          avail = avail - v;
+        }
+      }
+    });
+
+    usageByQueues.sort(function(a, b) {
+      return b.value - a.value;
+    });
+
+    usageByQueues = this.mergeLongTails(usageByQueues, 8);
+
+    usageByQueues.push({
+      label: "Available",
+      value: avail.toFixed(4)
+    });
+
+    this.colors = ColorUtils.getColors(usageByQueues.length, ["others", "good"], true);
+
+    this.renderDonutChart(usageByQueues, this.get("title"), this.get("showLabels"),
+      this.get("middleLabel"), "100%", "%");
+  },
+
+  didInsertElement: function() {
+    this.draw();
+  },
+})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js
index 2a90771..adedf9a 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js
@@ -90,7 +90,6 @@ export default Ember.Component.extend(ChartUtilsMixin, {
       .attr("class", "queue");
 
     circle.on('mouseover', function () {
-      circle.style("fill", this.queueColors[1]);
     }.bind(this));
     circle.on('mouseout', function () {
       if (circle != this.queues.selectedQueueCircle) {
@@ -206,7 +205,7 @@ export default Ember.Component.extend(ChartUtilsMixin, {
 
   renderQueueCapacities: function (queue, layout) {
     // Render bar chart
-    this.renderBarChart(this.charts.g, [{
+    this.renderCells(this.charts.g, [{
       label: "Cap",
       value: queue.get("capacity")
     }, {

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js
index e5da81a..359583d 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js
@@ -1,3 +1,4 @@
+
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -24,6 +25,7 @@ export default Ember.Component.extend({
     var ordering = this.get("ordering") ? true : this.get("ordering");
     var info = this.get("info") ? true : this.get("info");
     var bFilter = this.get("bFilter") ? true : this.get("bFilter");
+    var defaultSearch = this.get("defaultSearch") ? this.get("defaultSearch") : "";
 
     // Defines sorter for the columns if not default.
     // Can also specify a custom sorter.
@@ -66,11 +68,14 @@ export default Ember.Component.extend({
     console.log(orderArr[0]);
     Ember.$('#' + this.get('table-id')).DataTable({
       "paging":   paging,
-      "ordering": ordering, 
+      "ordering": ordering,
       "info":     info,
       "bFilter": bFilter,
       "order": orderArr,
-      "columnDefs": colDefs
+      "columnDefs": colDefs,
+      "oSearch": {
+        "sSearch": defaultSearch
+      }
     });
   }
 });

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js
new file mode 100644
index 0000000..4a121fe
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js
@@ -0,0 +1,198 @@
+/**
+ * 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.
+ */
+
+import BaseChartComponent from 'yarn-ui/components/base-chart-component';
+import Mock from 'yarn-ui/utils/mock';
+
+export default BaseChartComponent.extend({
+  MAX_BAR_HEIGHT: 120,
+  MAX_BAR_WIDTH: 30,
+  GAP: 5,
+  filter: "",
+  WIDTH_OF_SAMPLE: 200,
+
+  bindTP: function(element) {
+    element.on("mouseover", function() {
+      this.tooltip
+        .style("left", (d3.event.pageX) + "px")
+        .style("top", (d3.event.pageY - 28) + "px");
+      element.style("opacity", 1.0);
+    }.bind(this))
+      .on("mousemove", function() {
+        // Handle pie chart case
+        var text = element.attr("tooltiptext");
+
+        this.tooltip.style("opacity", .9);
+        this.tooltip.html(text)
+          .style("left", (d3.event.pageX) + "px")
+          .style("top", (d3.event.pageY - 28) + "px");
+      }.bind(this))
+      .on("mouseout", function() {
+        this.tooltip.style("opacity", 0);
+        element.style("opacity", 0.8);
+      }.bind(this));
+
+    element.on("click", function() {
+      if (element.attr("link")) {
+        this.tooltip.remove();
+        document.location.href = element.attr("link");
+      }
+    }.bind(this));
+  },
+
+  printSamples: function(n, layout, g, colorTitles) {
+    var yOffset = layout.margin * 3;
+
+    for (var i = 0; i < n; i++) {
+      var xOffset = layout.x2 - this.WIDTH_OF_SAMPLE - layout.margin;
+      g.append("rect").
+        attr("fill", this.colors[i]).
+        attr("x", xOffset).
+        attr("y", yOffset).
+        attr("width", 20).
+        attr("height", 20);
+
+      g.append("text").
+        attr("x", xOffset + 30).
+        attr("y", yOffset + 10).
+        text(colorTitles[i]);
+
+      yOffset = yOffset + 30;
+    }
+  },
+
+  // data:
+  //    [[{value=xx, bindText=xx}, {value=yy, bindText=yy}],  [  ...    ]]
+  //     __________________________________________________   ___________
+  //                          bar-1                              bar-2
+  show: function (data, title, colorTitles) {
+    var width = this.MAX_BAR_WIDTH;
+    var height = this.MAX_BAR_HEIGHT;
+
+    this.chart.g.remove();
+    this.chart.g = this.chart.svg.append("g");
+    var g = this.chart.g;
+    var layout = this.getLayout();
+    layout.margin = 50;
+
+    var nBarPerRow = Math.floor((layout.x2 - layout.x1 - 3 * layout.margin -
+      this.WIDTH_OF_SAMPLE) /
+      (width + this.GAP));
+
+    var xOffset;
+    var yOffset = layout.margin * 2;
+
+    var maxValue = 0;
+    var maxN = 0;
+    for (var i = 0; i < data.length; i++) {
+      var total = 0;
+      for (var j = 0; j < data[i].length; j++) {
+        total += data[i][j].value;
+      }
+
+      if (total > maxValue) {
+        maxValue = total;
+      }
+      if (data[i].length > maxN) {
+        maxN = data[i].length;
+      }
+    }
+
+    // print samples
+    this.printSamples(maxN, layout, g, colorTitles);
+
+    // print data
+    data.sort(function(a, b) {
+      return b[0].value - a[0].value;
+    });
+
+    for (var i = 0; i < data.length; i++) {
+      if (i % nBarPerRow == 0) {
+        xOffset = layout.margin;
+        yOffset += layout.margin + height;
+      }
+
+      var leftTopY = yOffset;
+      for (var j = 0; j < data[i].length; j++) {
+        var dy = data[i][j].value * height / maxValue;
+        if (dy > 0) {
+          leftTopY = leftTopY - dy;
+
+          var node = g.append("rect").
+            attr("fill", this.colors[j]).
+            attr("x", xOffset).
+            attr("y", leftTopY).
+            attr("width", width).
+            attr("height", dy).
+            attr("tooltiptext",
+              (data[i][j].bindText) ? data[i][j].bindText : data[i][j].value).
+            attr("link", data[i][j].link)
+            .style("opacity", 0.8);
+
+          this.bindTP(node);
+        }
+      }
+
+      if (data[i].length == 1) {
+        g.append("text")
+          .text(data[i][0].value)
+          .attr("y", leftTopY - 10)
+          .attr("x", xOffset + width / 2)
+          .attr("class", "heatmap-cell")
+          .style("fill", "black");
+      }
+
+      xOffset += width + this.GAP;
+    }
+
+    layout.y2 = yOffset + layout.margin;
+    this.adjustMaxHeight(layout.y2);
+    this.renderTitleAndBG(g, title, layout, false);
+  },
+
+  draw: function(data, title, textWidth) {
+    this.initChart(true);
+    //Mock.initMockNodesData(this);
+
+    // mock data
+    var arr = [];
+    for (var i = 0; i < 5; i++) {
+      var subArr = [];
+      for (var j = 0; j < Math.random() * 4 + 1; j++) {
+        subArr.push({
+          value : Math.abs(Math.random())
+        });
+      }
+      arr.push(subArr);
+    }
+
+    this.show(
+      arr, this.get("title"));
+  },
+
+  didInsertElement: function () {
+    this.draw();
+  },
+
+  actions: {
+    applyFilter: function(event) {
+      this.filter = event.srcElement.value;
+      this.didInsertElement();
+    }
+  }
+})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js
index 8a2b3de..516b114 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js
@@ -105,7 +105,7 @@ export default Ember.Component.extend({
     var border = 30;
     var singleBarHeight = this.getPerItemHeight();
     var gap = this.getPerItemGap();
-    var textWidth = 50;
+    var textWidth = 200;
     /*
      start-time                              end-time
       |--------------------------------------|

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js
index 1af98ab..5e7cfa0 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js
@@ -18,6 +18,8 @@
 
 import Ember from 'ember';
 
+const INBETWEEN_HEIGHT = 130;
+
 export default Ember.Component.extend({
   // Map: <queue-name, queue>
   map : undefined,
@@ -124,12 +126,25 @@ export default Ember.Component.extend({
     var nodeEnter = node.enter().append("g")
       .attr("class", "node")
       .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
-      .on("click", function(d,i){
+      .on("mouseover", function(d,i){
         if (d.queueData.get("name") != this.get("selected")) {
-            document.location.href = "#/yarn-queue/" + d.queueData.get("name");
+            document.location.href = "#/yarn-queues/" + d.queueData.get("name");
         }
-      }.bind(this));
-      // .on("click", click);
+
+        Ember.run.later(this, function () {
+          var treeWidth = this.maxDepth * 200;
+          var treeHeight = this.numOfLeafQueue * INBETWEEN_HEIGHT;
+          var tree = d3.layout.tree().size([treeHeight, treeWidth]);
+          var diagonal = d3.svg.diagonal()
+            .projection(function(d) { return [d.y, d.x]; });
+
+          this.update(this.treeData, this.treeData, tree, diagonal);
+        }, 100);
+
+      }.bind(this))
+    .on("click", function (d) {
+      document.location.href = "#/yarn-queue/" + d.queueData.get("name");
+    });
 
     nodeEnter.append("circle")
       .attr("r", 1e-6)
@@ -148,6 +163,7 @@ export default Ember.Component.extend({
     nodeEnter.append("text")
       .attr("x", function(d) { return 0; })
       .attr("dy", ".35em")
+      .attr("fill", "white")
       .attr("text-anchor", function(d) { return "middle"; })
       .text(function(d) {
         var usedCap = d.queueData.get("usedCapacity");
@@ -161,9 +177,9 @@ export default Ember.Component.extend({
 
     // append queue name
     nodeEnter.append("text")
-      .attr("x", function(d) { return 40; })
-      .attr("dy", ".35em")
-      .attr("text-anchor", function(d) { return "start"; })
+      .attr("x", "0px")
+      .attr("dy", "45px")
+      .attr("text-anchor", "middle")
       .text(function(d) { return d.name; })
       .style("fill-opacity", 1e-6);
 
@@ -173,14 +189,21 @@ export default Ember.Component.extend({
       .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
 
     nodeUpdate.select("circle")
-      .attr("r", 20)
+      .attr("r", 30)
       .attr("href", 
         function(d) {
           return "#/yarn-queues/" + d.queueData.get("name");
         })
+      .style("stroke-width", function(d) {
+        if (d.queueData.get("name") == this.get("selected")) {
+          return 7;
+        } else {
+          return 2;
+        }
+      }.bind(this))
       .style("stroke", function(d) {
         if (d.queueData.get("name") == this.get("selected")) {
-          return "red";
+          return "gray";
         } else {
           return "gray";
         }
@@ -239,7 +262,7 @@ export default Ember.Component.extend({
 
     var margin = {top: 20, right: 120, bottom: 20, left: 120};
     var treeWidth = this.maxDepth * 200;
-    var treeHeight = this.numOfLeafQueue * 80;
+    var treeHeight = this.numOfLeafQueue * INBETWEEN_HEIGHT;
     var width = treeWidth + margin.left + margin.right;
     var height = treeHeight + margin.top + margin.bottom;
     var layout = { };

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js
index dc2f6e4..22e6267 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js
@@ -20,4 +20,13 @@ import Ember from 'ember';
 
 export default Ember.Controller.extend({
   loading: true,
+
+  breadcrumbs: [{
+    text: "Home",
+    routeName: 'application'
+  }, {
+    text: "Cluster Overview",
+    routeName: 'cluster-overview',
+  }]
+
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js
new file mode 100644
index 0000000..a458842
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+  breadcrumbs: Ember.computed("model.attempt.appId", function () {
+    var appId = this.get("model.attempt.appId");
+    return [{
+      text: "Home",
+      routeName: 'application'
+    },{
+      text: "Applications",
+      routeName: 'yarn-apps'
+    }, {
+      text: `App [${appId}]`,
+      routeName: 'yarn-app',
+      model: appId
+    }, {
+      text: "Attempt",
+    }];
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js
new file mode 100644
index 0000000..9ebc2a6
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+  breadcrumbs: Ember.computed("model.appId", function () {
+    var appId = this.get("model.appId");
+    return [{
+      text: "Home",
+      routeName: 'application'
+    },{
+      text: "Applications",
+      routeName: 'yarn-apps'
+    }, {
+      text: `App [${appId}]`,
+      routeName: 'yarn-app',
+      model: appId
+    }, {
+      text: "Attempts",
+    }];
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js
new file mode 100644
index 0000000..f6b9404
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js
@@ -0,0 +1,38 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+  breadcrumbs: Ember.computed("model.app.id", function () {
+    var appId = this.get("model.app.id");
+    return [{
+      text: "Home",
+      routeName: 'application'
+    },{
+      text: "Applications",
+      routeName: 'yarn-apps'
+    }, {
+      text: `App [${appId}]`,
+      routeName: 'yarn-app',
+      model: appId
+    }];
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js
index dc99fd1..396f83b 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js
@@ -19,4 +19,13 @@
 import Ember from 'ember';
 
 export default Ember.Controller.extend({
+
+  breadcrumbs: [{
+    text: "Home",
+    routeName: 'application'
+  }, {
+    text: "Applications",
+    routeName: 'yarn-apps',
+  }]
+
 });

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js
new file mode 100644
index 0000000..4bfe9d0
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+  breadcrumbs: Ember.computed("model.attempt.appId", function () {
+    var nodeInfo = this.get("model.nodeInfo");
+    return [{
+      text: "Home",
+      routeName: 'application'
+    },{
+      text: "Nodes",
+      routeName: 'yarn-nodes'
+    }, {
+      text: `Node [ ${nodeInfo.id} ]`,
+      href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
+    }, {
+      text: "Applications",
+    }];
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js
new file mode 100644
index 0000000..59c8591
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+  breadcrumbs: Ember.computed("model.nodeInfo", function () {
+    var nodeInfo = this.get("model.nodeInfo");
+    return [{
+      text: "Home",
+      routeName: 'application'
+    },{
+      text: "Nodes",
+      routeName: 'yarn-nodes'
+    }, {
+      text: `Node [ ${nodeInfo.id} ]`,
+      href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
+    }, {
+      text: "Containers",
+    }];
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js
new file mode 100644
index 0000000..e505022
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js
@@ -0,0 +1,37 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+  breadcrumbs: Ember.computed("model.attempt.appId", function () {
+    var nodeInfo = this.get("model.nodeInfo");
+    return [{
+      text: "Home",
+      routeName: 'application'
+    },{
+      text: "Nodes",
+      routeName: 'yarn-nodes'
+    }, {
+      text: `Node [ ${nodeInfo.id} ]`,
+      href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
+    }];
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js
new file mode 100644
index 0000000..fbe77fa
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+  needReload: true,
+  selectedQueue: undefined,
+
+  breadcrumbs: [{
+    text: "Home",
+    routeName: 'application'
+  }, {
+    text: "Nodes",
+    routeName: 'yarn-nodes',
+  }, {
+    text: "Heatmap",
+    routeName: 'yarn-nodes-heatmap',
+  }]
+
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js
new file mode 100644
index 0000000..b4bf0f0
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js
@@ -0,0 +1,33 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+  needReload: true,
+  selectedQueue: undefined,
+
+  breadcrumbs: [{
+    text: "Home",
+    routeName: 'application'
+  }, {
+    text: "Nodes",
+    routeName: 'yarn-nodes',
+  }]
+
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js
new file mode 100644
index 0000000..e7bedd6
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js
@@ -0,0 +1,46 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+  needReload: true,
+  selectedQueue: undefined,
+
+  breadcrumbs: Ember.computed("model.selected", function () {
+    var queueName = this.get("model.selected");
+
+    return [{
+      text: "Home",
+      routeName: 'application'
+    }, {
+      text: "Queues",
+      routeName: 'yarn-queues',
+      model: 'root'
+    }, {
+      text: `Queue [ ${queueName} ]`,
+      routeName: 'yarn-queue',
+      model: queueName
+    }, {
+      text: "Applications",
+    }];
+
+  }),
+
+
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js
index 38cf352..0b4150f 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js
@@ -21,4 +21,24 @@ import Ember from 'ember';
 export default Ember.Controller.extend({
   needReload: true,
   selectedQueue: undefined,
+
+  breadcrumbs: Ember.computed("model.selected", function () {
+    var queueName = this.get("model.selected");
+
+    return [{
+      text: "Home",
+      routeName: 'application'
+    }, {
+      text: "Queues",
+      routeName: 'yarn-queues',
+      model: 'root'
+    }, {
+      text: `Queue [ ${queueName} ]`,
+      routeName: 'yarn-queue',
+      model: queueName
+    }];
+
+  }),
+
+
 });

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js
new file mode 100644
index 0000000..941e150
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+  needReload: true,
+  selectedQueue: undefined,
+
+  breadcrumbs: [{
+    text: "Home",
+    routeName: 'application'
+  }, {
+    text: "Queues",
+    routeName: 'yarn-queues',
+    model: 'root'
+  }]
+
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js
new file mode 100644
index 0000000..597962a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+  breadcrumbs: [{
+    text: "Home",
+    routeName: 'application'
+  }, {
+    text: "Applications",
+    routeName: 'yarn-apps',
+  }, {
+    text: "Long Running Services",
+    routeName: 'yarn-services',
+  }]
+
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js
index 981375a..bc6e27a 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js
@@ -125,7 +125,7 @@ export default DS.Model.extend({
     });
     arr.push({
       label: "Available",
-      value: this.get("available" + type)
+      value: Math.max(this.get("available" + type), 0)
     });
 
     return arr;

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js
index b913a33..f30d143 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js
@@ -30,6 +30,17 @@ export default DS.Model.extend({
   hosts: DS.attr('string'),
   logsLink: DS.attr('string'),
   state: DS.attr('string'),
+  appAttemptId: DS.attr('string'),
+
+  appId: Ember.computed("id",function () {
+    var id = this.get("id");
+    id = id.split("_");
+
+    id[0] = "application";
+    id.pop();
+
+    return id.join("_");
+  }),
 
   attemptStartedTime: function() {
     var startTime = this.get("startTime");

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js
index a96c17c..0a5df87 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js
@@ -36,6 +36,7 @@ export default DS.Model.extend({
   unmanagedApplication: DS.attr('string'),
   amNodeLabelExpression: DS.attr('string'),
   applicationTags: DS.attr('string'),
+  applicationType: DS.attr('string'),
   priority: DS.attr('number'),
   allocatedMB: DS.attr('number'),
   allocatedVCores: DS.attr('number'),
@@ -46,6 +47,9 @@ export default DS.Model.extend({
   preemptedResourceVCores: DS.attr('number'),
   numNonAMContainerPreempted: DS.attr('number'),
   numAMContainerPreempted: DS.attr('number'),
+  clusterUsagePercentage: DS.attr('number'),
+  queueUsagePercentage: DS.attr('number'),
+  currentAppAttemptId: DS.attr('string'),
 
   isFailed: function() {
     return this.get('finalStatus') == "FAILED"

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js
index 9a1082c..a15a20f 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js
@@ -89,4 +89,11 @@ export default DS.Model.extend({
     });
     return arr;
   }.property("availableVirtualCores", "usedVirtualCores"),
+
+  toolTipText: function() {
+    return "<p>Rack: " + this.get("rack") + '</p>' +
+           "<p>Host: " + this.get("nodeHostName") + '</p>' +
+           "<p>Used Memory: " + Math.round(this.get("usedMemoryMB")) + ' MB</p>' +
+           "<p>Available Memory: " + Math.round(this.get("availMemoryMB")) + ' MB</p>';
+  }.property(),
 });

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js
index 8f7ce5f..87a018d 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js
@@ -24,8 +24,15 @@ var Router = Ember.Router.extend({
 });
 
 Router.map(function() {
-  this.route('yarn-apps');
-  this.route('yarn-nodes');
+  this.route('yarn-apps', function () {
+    this.route('apps');
+    this.route('services');
+  });
+  this.route('yarn-nodes', function(){
+    this.route('table');
+    this.route('heatmap');
+  });
+  this.route('yarn-nodes-heatmap');
   this.route('yarn-node', { path: '/yarn-node/:node_id/:node_addr' });
   this.route('yarn-node-apps', { path: '/yarn-node-apps/:node_id/:node_addr' });
   this.route('yarn-node-app',
@@ -37,11 +44,15 @@ Router.map(function() {
   this.route('yarn-container-log', { path:
       '/yarn-container-log/:node_id/:node_addr/:container_id/:filename' });
   this.route('yarn-queue', { path: '/yarn-queue/:queue_name' });
+
   this.route('cluster-overview');
   this.route('yarn-app', { path: '/yarn-app/:app_id' });
   this.route('yarn-app-attempt', { path: '/yarn-app-attempt/:app_attempt_id'});
   this.route('error');
   this.route('notfound', { path: '*:' });
+  this.route('yarn-app-attempts', { path: '/yarn-app-attempts/:app_id' });
+  this.route('yarn-queues', { path: '/yarn-queues/:queue_name' });
+  this.route('yarn-queue-apps', { path: '/yarn-queue-apps/:queue_name' });
 });
 
 export default Router;

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js
index b7a5754..07b3792 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js
@@ -27,6 +27,8 @@ export default Ember.Route.extend({
      * error handler page.
      */
     error: function (error) {
+      Ember.Logger.log(error.stack);
+
       if (error && error.errors[0] &&
           error.errors[0].status == 404) {
         this.intermediateTransitionTo('/notfound');

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js
index 4b4e554..3689274 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js
@@ -20,7 +20,14 @@ import Ember from 'ember';
 
 export default Ember.Route.extend({
   model() {
-    return this.store.findAll('ClusterMetric');
+    return Ember.RSVP.hash({
+      clusterMetrics: this.store.findAll('ClusterMetric'),
+      apps: this.store.query('yarn-app',
+        {
+          state: "RUNNING"
+        }),
+      queues: this.store.findAll('yarn-queue'),
+    });
   },
 
   afterModel() {

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js
new file mode 100644
index 0000000..1a526c7
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js
@@ -0,0 +1,30 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+  model(param) {
+    return this.store.query('yarn-app-attempt', { appId: param.app_id}).then(function (attempts) {
+      return {
+        appId: param.app_id,
+        attempts: attempts
+      };
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/53874603/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js
index f5384b8..ab84632 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js
@@ -22,7 +22,22 @@ export default Ember.Route.extend({
   model(param) {
     return Ember.RSVP.hash({
       app: this.store.find('yarn-app', param.app_id),
-      attempts: this.store.query('yarn-app-attempt', { appId: param.app_id})
+
+      rmContainers: this.store.find('yarn-app', param.app_id).then(function(app) {
+        return this.store.query('yarn-app-attempt', {appId: param.app_id}).then(function (attempts) {
+          if (attempts && attempts.get('firstObject')) {
+            var appAttemptId = attempts.get('firstObject').get('appAttemptId');
+            var rmContainers = this.store.query('yarn-container',
+              {
+                app_attempt_id: appAttemptId,
+                is_rm: true
+              });
+            return rmContainers;
+          }
+        }.bind(this));
+      }.bind(this)),
+
+      nodes: this.store.findAll('yarn-rm-node'),
     });
   }
 });


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org