YARN-5496. Make Node Heatmap Chart categories clickable in new YARN UI. Contributed by Gergely Novák.

This commit is contained in:
Sunil G 2017-03-14 11:47:11 +05:30
parent 9832ae0ed8
commit e5f2eedcbf
3 changed files with 93 additions and 29 deletions

View File

@ -141,4 +141,8 @@ export default Ember.Component.extend({
}; };
return layout; return layout;
}, },
willDestroy: function() {
this.tooltip.remove();
}
}); });

View File

@ -26,17 +26,18 @@ export default BaseChartComponent.extend({
CELL_MARGIN: 2, CELL_MARGIN: 2,
RACK_MARGIN: 20, RACK_MARGIN: 20,
filter: "", filter: "",
selectedCategory: 0,
bindTP: function(element) { bindTP: function(element, cell) {
element.on("mouseover", function() { element.on("mouseover", function() {
this.tooltip this.tooltip
.style("left", (d3.event.pageX) + "px") .style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px"); .style("top", (d3.event.pageY - 28) + "px");
element.style("opacity", 1.0); cell.style("opacity", 1.0);
}.bind(this)) }.bind(this))
.on("mousemove", function() { .on("mousemove", function() {
// Handle pie chart case // Handle pie chart case
var text = element.attr("tooltiptext"); var text = cell.attr("tooltiptext");
this.tooltip.style("opacity", 0.9); this.tooltip.style("opacity", 0.9);
this.tooltip.html(text) this.tooltip.html(text)
@ -45,10 +46,45 @@ export default BaseChartComponent.extend({
}.bind(this)) }.bind(this))
.on("mouseout", function() { .on("mouseout", function() {
this.tooltip.style("opacity", 0); this.tooltip.style("opacity", 0);
element.style("opacity", 0.8); cell.style("opacity", 0.8);
}.bind(this)); }.bind(this));
}, },
bindSelectCategory: function(element, i) {
element.on("click", function() {
if (this.selectedCategory == i) {
// Remove selection for second click
this.selectedCategory = 0;
} else {
this.selectedCategory = i;
}
this.didInsertElement();
}.bind(this));
},
isNodeSelected: function(node) {
if (this.filter) {
var rack = node.get("rack");
var host = node.get("nodeHostName");
if (!rack.includes(this.filter) && !host.includes(this.filter)) {
return false;
}
}
if (this.selectedCategory === 0) {
return true;
}
var usage = node.get("usedMemoryMB") /
(node.get("usedMemoryMB") + node.get("availMemoryMB"))
var lowerLimit = (this.selectedCategory - 1) * 0.2;
var upperLimit = this.selectedCategory * 0.2;
if (lowerLimit <= usage && usage <= upperLimit) {
return true;
}
return false;
},
// data: // data:
// [{label=label1, value=value1}, ...] // [{label=label1, value=value1}, ...]
// ... // ...
@ -84,20 +120,32 @@ export default BaseChartComponent.extend({
for (i = 1; i <= 5; i++) { for (i = 1; i <= 5; i++) {
var ratio = i * 0.2 - 0.1; var ratio = i * 0.2 - 0.1;
g.append("rect") var rect = g.append("rect")
.attr("x", sampleXOffset) .attr("x", sampleXOffset)
.attr("y", sampleYOffset) .attr("y", sampleYOffset)
.attr("fill", colorFunc(ratio)) .attr("fill", this.selectedCategory === i ? "#2ca02c" : colorFunc(ratio))
.attr("width", this.SAMPLE_CELL_WIDTH) .attr("width", this.SAMPLE_CELL_WIDTH)
.attr("height", this.SAMPLE_HEIGHT); .attr("height", this.SAMPLE_HEIGHT)
g.append("text") .attr("class", "hyperlink");
this.bindSelectCategory(rect, i);
var text = g.append("text")
.text("" + (ratio * 100).toFixed(1) + "% Used") .text("" + (ratio * 100).toFixed(1) + "% Used")
.attr("y", sampleYOffset + this.SAMPLE_HEIGHT / 2 + 5) .attr("y", sampleYOffset + this.SAMPLE_HEIGHT / 2 + 5)
.attr("x", sampleXOffset + this.SAMPLE_CELL_WIDTH / 2) .attr("x", sampleXOffset + this.SAMPLE_CELL_WIDTH / 2)
.attr("class", "heatmap-cell"); .attr("class", "heatmap-cell hyperlink");
this.bindSelectCategory(text, i);
sampleXOffset += this.CELL_MARGIN + this.SAMPLE_CELL_WIDTH; sampleXOffset += this.CELL_MARGIN + this.SAMPLE_CELL_WIDTH;
} }
if (this.selectedCategory != 0) {
var text = g.append("text")
.text("Clear")
.attr("y", sampleYOffset + this.SAMPLE_HEIGHT / 2 + 5)
.attr("x", sampleXOffset + 20)
.attr("class", "heatmap-clear hyperlink");
this.bindSelectCategory(text, 0);
}
var chartXOffset = -1; var chartXOffset = -1;
for (i = 0; i < racksArray.length; i++) { for (i = 0; i < racksArray.length; i++) {
@ -118,22 +166,7 @@ export default BaseChartComponent.extend({
var host = data[j].get("nodeHostName"); var host = data[j].get("nodeHostName");
if (rack === racksArray[i]) { if (rack === racksArray[i]) {
if (!rack.includes(this.filter) && !host.includes(this.filter)) { this.addNode(g, xOffset, yOffset, colorFunc, data[j]);
this.addNode(g, xOffset, yOffset, colorFunc, data[j], false);
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; xOffset += this.CELL_MARGIN + this.CELL_WIDTH;
if (xOffset + this.CELL_MARGIN + this.CELL_WIDTH >= layout.x2 - if (xOffset + this.CELL_MARGIN + this.CELL_WIDTH >= layout.x2 -
layout.margin) { layout.margin) {
@ -162,7 +195,7 @@ export default BaseChartComponent.extend({
this.renderTitleAndBG(g, title, layout, false); this.renderTitleAndBG(g, title, layout, false);
}, },
addNode: function (g, xOffset, yOffset, colorFunc, data, selected) { addNode: function (g, xOffset, yOffset, colorFunc, data) {
var rect = g.append("rect") var rect = g.append("rect")
.attr("y", yOffset) .attr("y", yOffset)
.attr("x", xOffset) .attr("x", xOffset)
@ -171,13 +204,27 @@ export default BaseChartComponent.extend({
(data.get("usedMemoryMB") + data.get("availMemoryMB")))) (data.get("usedMemoryMB") + data.get("availMemoryMB"))))
.attr("width", this.CELL_WIDTH) .attr("width", this.CELL_WIDTH)
.attr("tooltiptext", data.get("toolTipText")); .attr("tooltiptext", data.get("toolTipText"));
if (selected) {
if (this.isNodeSelected(data)) {
rect.style("opacity", 0.8); rect.style("opacity", 0.8);
this.bindTP(rect); this.bindTP(rect, rect);
} else { } else {
rect.style("opacity", 0.8); rect.style("opacity", 0.8);
rect.attr("fill", "DimGray"); rect.attr("fill", "DimGray");
} }
var node_id = data.get("id"),
node_addr = data.get("nodeHTTPAddress"),
href = `#/yarn-node/${node_id}/${node_addr}`;
var a = g.append("a")
.attr("href", href);
var text = a.append("text")
.text(data.get("nodeHostName"))
.attr("y", yOffset + this.CELL_HEIGHT / 2 + 5)
.attr("x", xOffset + this.CELL_WIDTH / 2)
.attr("class", this.isNodeSelected(data) ? "heatmap-cell" : "heatmap-cell-notselected")
if (this.isNodeSelected(data)) {
this.bindTP(a, rect);
}
}, },
addPlaceholderNode: function(g, xOffset, yOffset) { addPlaceholderNode: function(g, xOffset, yOffset) {
@ -202,6 +249,7 @@ export default BaseChartComponent.extend({
actions: { actions: {
applyFilter: function(event) { applyFilter: function(event) {
this.filter = event.srcElement.value; this.filter = event.srcElement.value;
this.selectedCategory = 0;
this.didInsertElement(); this.didInsertElement();
} }
} }

View File

@ -63,6 +63,18 @@ text.heatmap-cell {
text-align: center; text-align: center;
} }
.hyperlink {
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.heatmap-clear {
fill: #337ab7;
}
text.heatmap-cell-notselected { text.heatmap-cell-notselected {
font: 14px sans-serif; font: 14px sans-serif;
font-weight: bold; font-weight: bold;