YARN-5496. Make Node Heatmap Chart categories clickable in new YARN UI. Contributed by Gergely Novák.
This commit is contained in:
parent
9832ae0ed8
commit
e5f2eedcbf
@ -141,4 +141,8 @@ export default Ember.Component.extend({
|
|||||||
};
|
};
|
||||||
return layout;
|
return layout;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
willDestroy: function() {
|
||||||
|
this.tooltip.remove();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user