diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-capacity-sunburst-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-capacity-sunburst-chart.js
new file mode 100644
index 00000000000..0fdb5d1b827
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-capacity-sunburst-chart.js
@@ -0,0 +1,338 @@
+/**
+ * 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 QueueSelector from 'yarn-ui/components/queue-selector';
+import Converter from 'yarn-ui/utils/converter';
+
+const MARGIN = 10;
+const LEGEND_WIDTH = 200;
+
+export default QueueSelector.extend({
+ queuesMap: undefined,
+ nodes: undefined,
+
+ tooltip : undefined,
+ svg: undefined,
+ g: undefined,
+
+ type: "used",
+ transitioning: false,
+
+ initTooltip: function() {
+ if (!this.tooltip) {
+ this.tooltip = d3.select("body")
+ .append("div")
+ .attr("class", "tooltip")
+ .attr("id", "chart-tooltip")
+ .style("opacity", 0);
+ }
+ },
+
+ bindTooltip: function(d) {
+ d.on("mouseover", function() {
+ this.tooltip
+ .style("left", (d3.event.pageX) + "px")
+ .style("top", (d3.event.pageY - 28) + "px");
+ }.bind(this))
+ .on("mousemove", function(d) {
+ // Handle pie chart case
+ var data = d;
+ if (d.data) {
+ data = d.data;
+ }
+
+ this.tooltip.style("opacity", 0.7);
+ 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))
+ .on("mouseout", function() {
+ this.tooltip.style("opacity", 0);
+ }.bind(this));
+ },
+
+ defineGradient: function(name, start, stop) {
+ var gradient = this.svg.append("defs")
+ .append("linearGradient")
+ .attr("id", name)
+ .attr("x1", "0%")
+ .attr("y1", "50%")
+ .attr("x2", "100%")
+ .attr("y2", "50%");
+ gradient.append("stop")
+ .attr("offset", "0%")
+ .attr("stop-color", start);
+ gradient.append("stop")
+ .attr("offset", "100%")
+ .attr("stop-color", stop);
+ },
+
+ round: function(number, decimals=4) {
+ var e = Math.pow(10, decimals);
+ return Math.round(number * e) / e;
+ },
+
+ partitionValue: function(d) {
+ if (this.type === "configured") {
+ return d.capacity.configured;
+ } else {
+ return d.capacity.used;
+ }
+ },
+
+ changeChartType: function(chartType, path, partition, arc) {
+ this.type = chartType;
+ this.sendAction("setSunburstChartType", this.type);
+ d3.selectAll(".radio-center")
+ .style("opacity", 0);
+ d3.selectAll("#radio-" + this.type)
+ .style("opacity", 1);
+ this.transitioning = true;
+ path.data(partition.value(this.partitionValue.bind(this)).nodes)
+ .transition()
+ .duration(1000)
+ .attrTween("d", function(finish) {
+ var start = {
+ x: finish.xOld,
+ dx: finish.dxOld
+ };
+ return function(t) {
+ var end = d3.interpolate(start, finish)(t);
+ finish.xOld = end.x;
+ finish.dxOld = end.dx;
+ return arc(end);
+ };
+ })
+ .each("end", function() {
+ this.transitioning = false;
+ }.bind(this));
+ },
+
+ reDraw: function() {
+ this.initData();
+
+ var parentId = this.get("parentId");
+ var parent = d3.select("#" + parentId);
+ parent.selectAll("*").remove();
+ var bbox = parent.node().getBoundingClientRect();
+ this.width = bbox.width;
+ this.height = this.width - LEGEND_WIDTH;
+
+ this.svg = d3
+ .select("#" + parentId)
+ .append("svg")
+ .attr("width", this.width)
+ .attr("height", this.height);
+ this.g = this.svg.append("g");
+
+ var radius = (Math.max(400, (this.width - 2 * MARGIN)) - LEGEND_WIDTH) / 2;
+
+ var cx = (this.width - LEGEND_WIDTH) / 2;
+ var cy = MARGIN + radius;
+
+ var partition = d3.layout.partition()
+ .sort(null)
+ .size([2 * Math.PI, radius])
+ .value(this.partitionValue.bind(this));
+
+ var arc = d3.svg.arc()
+ .startAngle(function(d) { return d.x; })
+ .endAngle(function(d) { return d.x + d.dx; })
+ .innerRadius(function(d) { return d.y; })
+ .outerRadius(function(d) { return d.y + d.dy; });
+
+ var underCapColorStart = "#26bbf0", underCapColorEnd = "#1c95c0";
+ var overCapColorStart = "#ffbc0b", overCapColorEnd = "#dca41b";
+ var underCapColorFunc = d3.interpolate(
+ d3.rgb(underCapColorStart), d3.rgb(underCapColorEnd));
+ var overCapColorFunc = d3.interpolate(
+ d3.rgb(overCapColorStart), d3.rgb(overCapColorEnd));
+ this.defineGradient("under", underCapColorStart, underCapColorEnd);
+ this.defineGradient("over", overCapColorStart, overCapColorEnd);
+
+ var path = this.g.datum(this.treeData).selectAll("path")
+ .data(partition.nodes)
+ .enter()
+ .append("path")
+ .attr("d", arc)
+ .style("stroke", "#fff")
+ .style("fill", function(d) {
+ if (d.capacity.used > d.capacity.configured) {
+ return overCapColorFunc(d.capacity.used / d.capacity.max);
+ }
+ return underCapColorFunc(d.capacity.used / d.capacity.configured);
+ })
+ .each(function(d) {
+ d.xOld = d.x;
+ d.dxOld = d.dx;
+ })
+ .attr("transform", "translate(" + cx + "," + cy + ")");
+
+ path.on("mousemove", function(d) {
+ if (this.transitioning) { return; }
+
+ this.g.selectAll("path").transition();
+ var path = [];
+ var current = d;
+ while (current) {
+ path.push(current);
+ current = current.parent;
+ }
+ this.g.selectAll("path")
+ .style("opacity", 0.3);
+ this.g.selectAll("path")
+ .filter(function(d) {
+ return path.indexOf(d) !== -1;
+ })
+ .style("opacity", 1);
+
+ this.tooltip.style("opacity", 0.7);
+ this.tooltip.html(
+ "
" + d.name + "
" +
+ "Used: " + this.round(d.capacity.used) + "%
" +
+ "Configured: " + this.round(d.capacity.configured) + "%
" +
+ "Max: " + this.round(d.capacity.max) + "%
")
+ .style("left", d3.event.pageX + "px")
+ .style("top", (d3.event.pageY - 28) + "px");
+ }.bind(this));
+
+ path.on("mouseout", function() {
+ if (this.transitioning) { return; }
+
+ this.g.selectAll("path")
+ .transition()
+ .duration(500)
+ .style("opacity", 1);
+ this.tooltip.style("opacity", 0);
+ }.bind(this));
+
+ path.on("click", function (d) {
+ if (d.queueData.get("name") !== this.get("selected")) {
+ document.location.href =
+ "#/yarn-queues/" + d.queueData.get("name") +
+ "!?viewType=sunburst&sunburstChartType=" + this.type;
+ }
+ }.bind(this));
+
+ path.on("dblclick", function(d) {
+ document.location.href =
+ "#/yarn-queue/" + d.queueData.get("name") + "/apps";
+ });
+
+ if (this.get("showLabels")) {
+ var lx = this.width - LEGEND_WIDTH;
+ var ly = 75;
+ var squareW = 15;
+ var margin = 10;
+
+ var labels = [
+ {label: "Under capacity", gradient: "url(#under)"},
+ {label: "Over capacity", gradient: "url(#over)"}
+ ];
+ var select = this.g.selectAll("rect")
+ .data(labels)
+ .enter();
+ select.append("rect")
+ .attr("fill", function(d) { return d.gradient; })
+ .attr("x", lx)
+ .attr("y", function(d, i) {
+ return ly + (squareW + margin) * i + margin;
+ })
+ .attr("width", squareW)
+ .attr("height", squareW);
+ select.append("text")
+ .attr("x", lx + squareW + margin)
+ .attr("y", function(d, i) {
+ return ly + 5 + (squareW + margin) * i + margin + squareW / 2;
+ })
+ .text(function(d) { return d.label; });
+
+ this.g.append("text")
+ .attr("x", lx - 2)
+ .attr("y", ly + (squareW + margin) * 4 + margin)
+ .style("font-weight", "bold")
+ .text("Chart type");
+ var types = [
+ {label: "Configured capacity", type: "configured"},
+ {label: "Used capacity", type: "used"}
+ ];
+ select = this.g.selectAll("circle")
+ .data(types)
+ .enter();
+ select.append("circle")
+ .attr("cx", lx + squareW / 2)
+ .attr("cy", function(d, i) {
+ return ly + (squareW + margin) * (5 + i) + margin;
+ })
+ .attr("r", squareW / 2)
+ .attr("fill", "white")
+ .attr("stroke", "black")
+ .on("click", function(d) {
+ this.changeChartType(d.type, path, partition, arc);
+ }.bind(this));
+ select.append("circle")
+ .attr("cx", lx + squareW / 2)
+ .attr("cy", function(d, i) {
+ return ly + (squareW + margin) * (5 + i) + margin;
+ })
+ .attr("r", squareW / 2 - 2)
+ .attr("fill", "green")
+ .attr("id", function(d) { return "radio-" + d.type; })
+ .attr("class", "radio-center")
+ .attr("opacity", function(d) {
+ return d.type === this.type ? 1 : 0;
+ }.bind(this))
+ .on("click", function(d) {
+ this.type = d.type;
+ this.changeChartType(d.type, path, partition, arc);
+ }.bind(this));
+ select.append("text")
+ .attr("x", lx + squareW + margin)
+ .attr("y", function(d, i) {
+ return ly + 6 + (squareW + margin) * (5 + i) + margin;
+ })
+ .text(function(d) { return d.label; });
+ }
+
+ this.transitioning = true;
+ path.transition()
+ .duration(500)
+ .attrTween("d", function(finish) {
+ var start = {x: 0, dx: 0};
+ return function(d) {
+ return arc(d3.interpolate(start, finish)(d));
+ };
+ })
+ .each("end", function() {
+ this.transitioning = false;
+ }.bind(this));
+ },
+
+ didInsertElement: function() {
+ this.initTooltip();
+ this.reDraw();
+ },
+
+ willDestroy: function() {
+ this.tooltip.remove();
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.js
index 2cecefb7720..2e0e351a129 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.js
@@ -23,6 +23,15 @@ export default Ember.Component.extend(Ember.TargetActionSupport,{
filterQueuesByPartition(filter) {
this.set("filteredPartition", filter);
this.sendAction("setFilter", filter);
+ },
+ showTreeView() {
+ this.sendAction("setViewType", "tree");
+ },
+ showSunburstView() {
+ this.sendAction("setViewType", "sunburst");
+ },
+ setSunburstChartType(param) {
+ this.sendAction("setSunburstChartType", param);
}
},
didInsertElement: function() {
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-selector.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-selector.js
new file mode 100644
index 00000000000..ea32356b6fa
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-selector.js
@@ -0,0 +1,145 @@
+/**
+ * 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 {PARTITION_LABEL} from '../constants';
+
+export default Ember.Component.extend({
+ // Map:
+ queuesMap: undefined,
+
+ // Normalized data for d3
+ treeData: undefined,
+
+ // folded queues, folded[] == true means is folded
+ foldedQueues: {},
+
+ // maxDepth
+ maxDepth: 0,
+
+ // num of leaf queue, folded queue is treated as leaf queue
+ numOfLeafQueue: 0,
+
+ used: undefined,
+ max: undefined,
+
+ didUpdateAttrs: function({ oldAttrs, newAttrs }) {
+ if (oldAttrs.filteredPartition.value !== newAttrs.filteredPartition.value) {
+ this.reDraw();
+ }
+ },
+
+ initData: function() {
+ this.queuesMap = {};
+ this.treeData = {};
+ this.maxDepth = 0;
+ this.numOfLeafQueue = 0;
+
+ this.get("model").forEach(
+ function(o) {
+ this.queuesMap[o.id] = o;
+ }.bind(this)
+ );
+
+ // var selected = this.get("selected");
+ this.used = this.get("used");
+ this.max = this.get("max");
+ this.initQueue("root", 1, this.treeData);
+ },
+
+ // get Children array of given queue
+ getChildrenNamesArray: function(q) {
+ var namesArr = [];
+
+ // Folded queue's children is empty
+ if (this.foldedQueues[q.get("name")]) {
+ return namesArr;
+ }
+
+ var names = q.get("children");
+ if (names) {
+ names.forEach(function(name) {
+ namesArr.push(name);
+ });
+ }
+
+ return namesArr;
+ },
+
+ // Init queues
+ initQueue: function(queueName, depth, node) {
+ if (!queueName || !this.queuesMap[queueName]) {
+ // Queue is not existed
+ return false;
+ }
+ if (depth > this.maxDepth) {
+ this.maxDepth = this.maxDepth + 1;
+ }
+
+ var queue = this.queuesMap[queueName];
+
+ if (
+ this.filteredPartition &&
+ !queue.get("partitions").contains(this.filteredPartition)
+ ) {
+ return false;
+ }
+
+ var names = this.getChildrenNamesArray(queue);
+
+ node.name = queueName;
+ node.parent = queue.get("parent");
+ node.queueData = queue;
+ node.capacity = {
+ max: this.getMaxCapacity(queue.get("partitionMap"), this.filteredPartition),
+ configured: this.getConfiguredCapacity(queue.get("partitionMap"), this.filteredPartition),
+ used: this.getUsedCapacity(queue.get("partitionMap"), this.filteredPartition)
+ };
+
+ if (names.length > 0) {
+ node.children = [];
+
+ names.forEach(
+ function(name) {
+ var childQueueData = {};
+ node.children.push(childQueueData);
+ const status = this.initQueue(name, depth + 1, childQueueData);
+ if (!status) {
+ node.children.pop();
+ }
+ }.bind(this)
+ );
+ } else {
+ this.numOfLeafQueue = this.numOfLeafQueue + 1;
+ }
+
+ return true;
+ },
+
+ getUsedCapacity: function(partitionMap, filter=PARTITION_LABEL) {
+ return partitionMap[filter].absoluteUsedCapacity;
+ },
+
+ getConfiguredCapacity: function(partitionMap, filter=PARTITION_LABEL) {
+ return partitionMap[filter].absoluteCapacity;
+ },
+
+ getMaxCapacity: function(partitionMap, filter=PARTITION_LABEL) {
+ return partitionMap[filter].absoluteMaxCapacity;
+ },
+})
\ No newline at end of file
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 5168c0e0a7c..5ef4d7e6caf 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
@@ -17,120 +17,13 @@
*/
import Ember from "ember";
-import {PARTITION_LABEL} from '../constants';
+import QueueSelector from 'yarn-ui/components/queue-selector';
const INBETWEEN_HEIGHT = 130;
-export default Ember.Component.extend({
- // Map:
- map: undefined,
-
- // Normalized data for d3
- treeData: undefined,
-
- // folded queues, folded[] == true means is folded
- foldedQueues: {},
-
- // maxDepth
- maxDepth: 0,
-
- // num of leaf queue, folded queue is treated as leaf queue
- numOfLeafQueue: 0,
-
- // mainSvg
+export default QueueSelector.extend({
mainSvg: undefined,
- used: undefined,
- max: undefined,
-
- didUpdateAttrs: function({ oldAttrs, newAttrs }) {
- if (oldAttrs.filteredPartition.value !== newAttrs.filteredPartition.value) {
- this.reDraw();
- }
- },
- // Init data
- initData: function() {
- this.map = {};
- this.treeData = {};
- this.maxDepth = 0;
- this.numOfLeafQueue = 0;
-
- this.get("model").forEach(
- function(o) {
- this.map[o.id] = o;
- }.bind(this)
- );
-
- // var selected = this.get("selected");
- this.used = this.get("used");
- this.max = this.get("max");
- this.initQueue("root", 1, this.treeData);
- },
-
- // get Children array of given queue
- getChildrenNamesArray: function(q) {
- var namesArr = [];
-
- // Folded queue's children is empty
- if (this.foldedQueues[q.get("name")]) {
- return namesArr;
- }
-
- var names = q.get("children");
- if (names) {
- names.forEach(function(name) {
- namesArr.push(name);
- });
- }
-
- return namesArr;
- },
-
- // Init queues
- initQueue: function(queueName, depth, node) {
- if (!queueName || !this.map[queueName]) {
- // Queue is not existed
- return false;
- }
- if (depth > this.maxDepth) {
- this.maxDepth = this.maxDepth + 1;
- }
-
- var queue = this.map[queueName];
-
- if (
- this.filteredPartition &&
- !queue.get("partitions").contains(this.filteredPartition)
- ) {
- return false;
- }
-
- var names = this.getChildrenNamesArray(queue);
-
- node.name = queueName;
- node.parent = queue.get("parent");
- node.queueData = queue;
-
- if (names.length > 0) {
- node.children = [];
-
- names.forEach(
- function(name) {
- var childQueueData = {};
- node.children.push(childQueueData);
- const status = this.initQueue(name, depth + 1, childQueueData);
- if (!status) {
- node.children.pop();
- }
- }.bind(this)
- );
- } else {
- this.numOfLeafQueue = this.numOfLeafQueue + 1;
- }
-
- return true;
- },
-
update: function(source, root, tree, diagonal) {
var duration = 300;
var i = 0;
@@ -163,6 +56,7 @@ export default Ember.Component.extend({
if (d.queueData.get("name") !== this.get("selected")) {
document.location.href =
"#/yarn-queues/" + d.queueData.get("name") + "!";
+ this.set("selected", d.queueData.get("name"));
}
Ember.run.later(
@@ -174,7 +68,6 @@ export default Ember.Component.extend({
var diagonal = d3.svg.diagonal().projection(function(d) {
return [d.y + 50, d.x];
});
-
this.update(this.treeData, this.treeData, tree, diagonal);
},
100
@@ -192,7 +85,9 @@ export default Ember.Component.extend({
.style(
"fill",
function(d) {
- const usedCapacity = getUsedCapacity(d.queueData.get("partitionMap"), this.filteredPartition);
+ const usedCapacity =
+ this.getUsedCapacity(d.queueData.get("partitionMap"),
+ this.filteredPartition);
if (usedCapacity <= 60.0) {
return "#60cea5";
} else if (usedCapacity <= 100.0) {
@@ -216,7 +111,7 @@ export default Ember.Component.extend({
})
.text(
function(d) {
- const usedCapacity = getUsedCapacity(d.queueData.get("partitionMap"), this.filteredPartition);
+ const usedCapacity = this.getUsedCapacity(d.queueData.get("partitionMap"), this.filteredPartition);
if (usedCapacity >= 100.0) {
return usedCapacity.toFixed(0) + "%";
} else {
@@ -336,18 +231,16 @@ export default Ember.Component.extend({
var width = treeWidth + margin.left + margin.right;
var height = treeHeight + margin.top + margin.bottom;
- if (this.mainSvg) {
- this.mainSvg.selectAll("*").remove();
- } else {
- this.mainSvg = d3
- .select("#" + this.get("parentId"))
- .append("svg")
- .attr("width", width)
- .attr("height", height)
- .attr("class", "tree-selector");
- }
-
- this.mainSvg
+ var parentId = this.get("parentId");
+ var parent = d3.select("#" + parentId);
+ parent.selectAll("*").remove();
+ this.mainSvg = parent
+ .append("svg")
+ .attr("width", width)
+ .attr("height", height)
+ .attr("class", "tree-selector");
+
+ this.g = this.mainSvg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
@@ -369,9 +262,4 @@ export default Ember.Component.extend({
didInsertElement: function() {
this.reDraw();
}
-});
-
-
-const getUsedCapacity = (partitionMap, filter=PARTITION_LABEL) => {
- return partitionMap[filter].absoluteUsedCapacity;
-};
\ No newline at end of file
+});
\ No newline at end of file
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
index 6cc87675b50..51233d33b80 100644
--- 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
@@ -24,6 +24,9 @@ export default Ember.Controller.extend({
selectedQueue: undefined,
showLoading: true,
filteredPartition: PARTITION_LABEL,
+ viewType: "tree",
+ sunburstChartType: "used",
+ queryParams: ["viewType", "sunburstChartType"],
breadcrumbs: [
{
@@ -46,10 +49,18 @@ export default Ember.Controller.extend({
// reset it to root
if (!selectedQueue.get('partitions').contains(partition)) {
const root = model.queues.get('firstObject');
- document.location.href = "#/yarn-queues/" + root.get("id") + "!";
+ document.location.href = "#/yarn-queues/" + root.get("id") + "!?" +
+ "viewType=" + this.viewType +
+ "&sunburstChartType=" + this.sunburstChartType;
this.set("model.selectedQueue", root);
this.set("model.selected", root.get('id'));
}
+ },
+ setViewType(param) {
+ this.set("viewType", param);
+ },
+ setSunburstChartType(param) {
+ this.set("sunburstChartType", param);
}
}
});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/capitalize.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/capitalize.js
new file mode 100644
index 00000000000..67b0c451223
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/capitalize.js
@@ -0,0 +1,27 @@
+/**
+ * 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 function capitalize(params) {
+ const string = params[0];
+ return string.capitalize();
+}
+
+export default Ember.Helper.helper(capitalize);
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-navigator.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-navigator.hbs
index b063aae8eda..4bfbc50c9c1 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-navigator.hbs
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-navigator.hbs
@@ -19,27 +19,58 @@
-
-
- {{#if filteredPartition}}
- {{model.firstObject.type}} scheduler - Showing queues from partition {{lower filteredPartition}}
- {{else}}
- {{model.firstObject.type}} scheduler - Showing queues from all partitions
- {{/if}}
-
- {{#if (eq model.firstObject.type "capacity")}}
-
-
-
-
+
+
- {{/if}}
- {{tree-selector model=model parentId="tree-selector-container" selected=selected used=used max=max filteredPartition=filteredPartition}}
+
+
+ {{#if (eq viewType "tree")}}
+ {{tree-selector model=model parentId="queue-selector" selected=selected used=used max=max
+ filteredPartition=filteredPartition}}
+ {{else}}
+ {{queue-capacity-sunburst-chart model=model showLabels=true parentId="queue-selector"
+ selected=selected filteredPartition=filteredPartition type=sunburstChartType
+ setSunburstChartType=(action setSunburstChartType) }}
+ {{/if}}
+
+
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/capacity-queue.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/capacity-queue.hbs
index 9ad2a6f1a5d..c6802142bcc 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/capacity-queue.hbs
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/capacity-queue.hbs
@@ -17,7 +17,9 @@
}}
{{queue-navigator model=model.queues selected=model.selected
- used="usedCapacity" max="absMaxCapacity" setFilter=(action setFilter)}}
+ used="usedCapacity" max="absMaxCapacity" setFilter=(action setFilter)
+ setViewType=(action setViewType) viewType=viewType
+ setSunburstChartType=(action setSunburstChartType) sunburstChartType=sunburstChartType}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/fair-queue.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/fair-queue.hbs
index dcc80c10b30..d8646f8327e 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/fair-queue.hbs
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/fair-queue.hbs
@@ -17,7 +17,9 @@
}}
{{queue-navigator model=model.queues selected=model.selected
- used="usedResources.memory" max="clusterResources.memory"}}
+ used="usedResources.memory" max="clusterResources.memory" setFilter=(action setFilter)
+ setViewType=(action setViewType) viewType=viewType
+ setSunburstChartType=(action setSunburstChartType) sunburstChartType=sunburstChartType}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/fifo-queue.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/fifo-queue.hbs
index 98db5cb4153..f94ccc849c5 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/fifo-queue.hbs
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/yarn-queue/fifo-queue.hbs
@@ -17,7 +17,9 @@
}}
{{queue-navigator model=model.queues selected=model.selected
- used="usedNodeCapacity" max="totalNodeCapacity"}}
+ used="usedNodeCapacity" max="totalNodeCapacity" setFilter=(action setFilter)
+ setViewType=(action setViewType) viewType=viewType
+ setSunburstChartType=(action setSunburstChartType) sunburstChartType=sunburstChartType}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queues.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queues.hbs
index ede29946f0c..2901658bd5b 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queues.hbs
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queues.hbs
@@ -21,7 +21,9 @@
{{#if (eq model.queues.firstObject.type "capacity")}}
- {{yarn-queue.capacity-queue model=model setFilter=(action "setFilter") filteredPartition=filteredPartition}}
+ {{yarn-queue.capacity-queue model=model setFilter=(action "setFilter") filteredPartition=filteredPartition
+ setViewType=(action "setViewType") viewType=viewType
+ setSunburstChartType=(action "setSunburstChartType") sunburstChartType=sunburstChartType}}
{{else if (eq model.queues.firstObject.type "fair")}}
{{yarn-queue.fair-queue model=model}}
{{else}}