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 index c72d934..1d75bdd 100644 --- 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 @@ -22,6 +22,7 @@ import HrefAddressUtils from 'yarn-ui/utils/href-address-utils'; export default BaseUsageDonutChart.extend({ colors: d3.scale.category20().range(), + layoutName: "components/responsive-chart-component", draw: function() { var usageByApps = []; @@ -53,7 +54,7 @@ export default BaseUsageDonutChart.extend({ this.colors = ColorUtils.getColors(usageByApps.length, ["others", "good"], true); - this.renderDonutChart(usageByApps, this.get("title"), this.get("showLabels"), + this.renderDonutChart(usageByApps, this.get("title"), this.get("showLegend"), this.get("middleLabel"), "100%", "%"); }, }); \ No newline at end of file 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 aa41893..8caa756 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 @@ -32,6 +32,10 @@ export default Ember.Component.extend({ w: 0, tooltip: undefined }); + this.set("legend", { + svg: undefined, + g: undefined + }); }, initChart: function(removeLast = false) { @@ -145,4 +149,4 @@ export default Ember.Component.extend({ willDestroy: function() { this.tooltip.remove(); } -}); +}); \ No newline at end of file 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 82d2d46..eef78ed 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 @@ -17,15 +17,17 @@ */ import Ember from 'ember'; -import BaseChartComponent from 'yarn-ui/components/base-chart-component'; +import ResponsiveChartComponent from 'yarn-ui/components/responsive-chart-component'; import ColorUtils from 'yarn-ui/utils/color-utils'; import Converter from 'yarn-ui/utils/converter'; -export default BaseChartComponent.extend({ +export default ResponsiveChartComponent.extend({ + layoutName: "components/responsive-chart-component", + /* * data = [{label="xx", value=},{...}] */ - renderDonutChart: function(data, title, showLabels = false, + renderDonutChart: function(data, title, showLegend = false, middleLabel = "Total", middleValue = undefined, suffix = "") { var g = this.chart.g; var layout = this.getLayout(); @@ -48,24 +50,15 @@ export default BaseChartComponent.extend({ } } - //Width and height - var h = layout.y2 - layout.y1; - - // 50 is for title - var outerRadius = (h - 50 - 2 * layout.margin) / 2; + var outerRadius = 150; var innerRadius = outerRadius * 0.618; var arc = d3.svg.arc() .innerRadius(innerRadius) .outerRadius(outerRadius); - var cx; - var cy = layout.y1 + 50 + layout.margin + outerRadius; - if (showLabels) { - cx = layout.x1 + layout.margin + outerRadius; - } else { - cx = (layout.x1 + layout.x2) / 2; - } + var cx = layout.x1 + outerRadius; + var cy = layout.y1 + outerRadius; var pie = d3.layout.pie(); pie.sort(null); @@ -121,43 +114,48 @@ export default BaseChartComponent.extend({ }.bind(this)); // Show labels - if (showLabels) { - var lx = layout.x1 + layout.margin + outerRadius * 2 + 30; + if (showLegend) { var squareW = 15; var margin = 10; - var select = g.selectAll(".rect") - .data(data) - .enter(); - select.append("rect") - .attr("fill", function(d, i) { - return this.colors[i]; - }.bind(this)) - .attr("x", lx) - .attr("y", function(d, i) { - 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 + 80 + (squareW + margin) * i + layout.margin + squareW / 2; - }) - .text(function(d) { - var value = d.value; - if (this.get("type") === "memory") { - value = Converter.memoryToSimpliedUnit(value); - } - return d.label + ' = ' + value + suffix; - }.bind(this)); + var type = this.get("type"); + data.forEach(function(d, i) { + this.legend.g.append("rect") + .attr("fill", this.colors[i]) + .attr("x", 0) + .attr("y", (squareW + margin) * i) + .attr("width", squareW) + .attr("height", squareW); + var text; + if (d.link) { + var a = this.legend.g.append("a") + .attr("href", d.link); + text = a.append("text"); + } else { + text = this.legend.g.append("text"); + } + text + .attr("x", squareW + margin) + .attr("y", 5 + (squareW + margin) * i + squareW / 2) + .text(function() { + var value = d.value; + if (type === "memory") { + value = Converter.memoryToSimpliedUnit(value); + } + return d.label + ' = ' + value + suffix; + }); + }.bind(this)); + var bbox = this.legend.g.node().getBBox(); + var parentDiv = d3.select(this.legend.svg.node().parentNode); + parentDiv.style("width", this.get("legendWidth") + "px"); + this.legend.svg.attr("height", bbox.height); } if (middleLabel) { var highLightColor = this.colors[0]; - g.append("text").text(middleLabel).attr("x", cx).attr("y", cy - 10). + g.append("text").text(middleLabel).attr("x", cx).attr("y", cy - 18). attr("class", "donut-highlight-text").attr("fill", highLightColor); - g.append("text").text(middleValue).attr("x", cx).attr("y", cy + 15). + g.append("text").text(middleValue).attr("x", cx).attr("y", cy + 25). attr("class", "donut-highlight-sub").attr("fill", highLightColor); } @@ -168,7 +166,10 @@ export default BaseChartComponent.extend({ _dataChange: Ember.observer("data", function() { this.chart.g.selectAll("*").remove(); - if(this.get("data")) { + if (this.get("showLegend")) { + this.legend.g.selectAll("*").remove(); + } + if (this.get("data")) { this.draw(); } }), @@ -180,9 +181,8 @@ export default BaseChartComponent.extend({ 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")); + this.renderDonutChart(this.get("data"), this.get("title"), this.get("showLegend"), + this.get("middleLabel"), this.get("middleValue"), ""); }, didInsertElement: function() { 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 index c939aaf..7f7329d 100644 --- 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 @@ -22,6 +22,7 @@ import HrefAddressUtils from 'yarn-ui/utils/href-address-utils'; export default BaseUsageDonutChart.extend({ colors: d3.scale.category20().range(), + layoutName: "components/responsive-chart-component", draw: function() { var usageByQueues = []; @@ -56,7 +57,7 @@ export default BaseUsageDonutChart.extend({ this.colors = ColorUtils.getColors(usageByQueues.length, ["others", "good"], true); - this.renderDonutChart(usageByQueues, this.get("title"), this.get("showLabels"), + this.renderDonutChart(usageByQueues, this.get("title"), this.get("showLegend"), this.get("middleLabel"), "100%", "%"); }, diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/responsive-chart-component.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/responsive-chart-component.js new file mode 100644 index 0000000..54f98b1 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/responsive-chart-component.js @@ -0,0 +1,71 @@ +/** + * 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'; + +export default BaseChartComponent.extend({ + + initChart: function(removeLast = false) { + // Init tooltip if it is not initialized + // this.tooltip = d3.select("#chart-tooltip"); + if (!this.tooltip) { + this.tooltip = d3.select("body") + .append("div") + .attr("class", "tooltip") + .attr("id", "chart-tooltip") + .style("opacity", 0); + } + + var parentId = this.get("parentId"); + var parent = d3.select("#" + parentId); + + if (removeLast) { + var previousSvg = parent.select("svg"); + if (previousSvg) { + console.log(previousSvg); + previousSvg.remove(); + } + } + + var maxWidth = this.get("maxWidth"); + if (maxWidth) { + var table = parent.select("table"); + table.style("max-width", maxWidth + "px"); + } + + var chartDiv = parent.select(".chart"); + var bbox = chartDiv.node().getBoundingClientRect(); + this.chart.w = bbox.width; + this.chart.h = this.chart.w; + this.chart.svg = chartDiv.append("svg") + .attr("width", "100%") + .attr("id", parentId + "-svg") + .attr("viewBox", "0 0 300 300") + .attr("preserveAspectRatio", "xMinYMin meet"); + + this.chart.g = this.chart.svg.append("g"); + + var showLegend = this.get("showLegend"); + if (showLegend) { + var legendDiv = parent.select(".legend"); + this.legend.svg = legendDiv.append("svg") + .attr("width", "100%"); + this.legend.g = this.legend.svg.append("g"); + } + } +}); 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 22e6267..0fb819b 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 @@ -28,5 +28,4 @@ export default Ember.Controller.extend({ text: "Cluster Overview", routeName: 'cluster-overview', }] - }); \ No newline at end of file diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css index e3dfcd9..9bb8ed8 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css @@ -115,7 +115,7 @@ text.chart-title { } text.donut-highlight-text, text.donut-highlight-sub { - font-size: 15px; + font-size: 30px; font-family: sans-serif; text-anchor: middle; fill: Gray; @@ -123,7 +123,7 @@ text.donut-highlight-text, text.donut-highlight-sub { } text.donut-highlight-sub { - font-size: 23px; + font-size: 40px; margin-top: 10px; } @@ -306,6 +306,11 @@ li a.navigation-link.ember-view { width: 100%; } +.responsive-chart { + max-width: 500px; + margin: auto; +} + div.attempt-info-panel table { table-layout: fixed; } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/cluster-overview.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/cluster-overview.hbs index ac8f20a..654f236 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/cluster-overview.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/cluster-overview.hbs @@ -27,12 +27,14 @@
|
+
+
+ |
+ {{#if showLegend}}
+
+
+
+ |
+ {{/if}}
+