diff --git a/horizon/static/horizon/js/horizon.d3barchart.js b/horizon/static/horizon/js/horizon.d3barchart.js
index 103e2d624b..72f0b18be4 100644
--- a/horizon/static/horizon/js/horizon.d3barchart.js
+++ b/horizon/static/horizon/js/horizon.d3barchart.js
@@ -42,7 +42,7 @@
Json with variety of settings described below.
used-label-placement='string' OPTIONAL
- String determinign where the floating label stating number of percent
+ String determining where the floating label stating number of percent
will be placed. So far only left is supported.
width="integer" OPTIONAL
diff --git a/horizon/static/horizon/js/horizon.d3piechart.js b/horizon/static/horizon/js/horizon.d3piechart.js
index 4991295111..4aae5ddb1f 100644
--- a/horizon/static/horizon/js/horizon.d3piechart.js
+++ b/horizon/static/horizon/js/horizon.d3piechart.js
@@ -1,31 +1,64 @@
/*
- Draw pie chart in d3.
+ Draw pie charts in d3.
- To use, a div is required with the class .d3_pie_chart
- and a data-used attribute in the div
- that stores the percentage to fill the chart
+ To use, a div is required with the class .d3_pie_chart_usage or
+ .d3_pie_chart_distribution, and a data-used attribute in the div
+ that stores the data used to fill the chart.
- Example:
-
+
+ Example (distribution):
+
+
*/
-horizon.d3_pie_chart = {
- w: 100,
- h: 100,
- r: 45,
- bkgrnd: "#F2F2F2",
- frgrnd: "#006CCF",
- full: "#D0342B",
- nearlyfull: "orange",
+// Pie chart dimensions
+var WIDTH = 100;
+var HEIGHT = 100;
+var RADIUS = 45;
+// Colors
+var BKGRND = "#F2F2F2";
+var FRGRND = "#006CCF";
+var FULL = "#D0342B";
+var NEARLY_FULL = "#FFA500";
+var STROKE = "#CCCCCC";
+
+
+function create_vis(chart) {
+ return d3.select(chart).append("svg:svg")
+ .attr("class", "chart")
+ .attr("width", WIDTH)
+ .attr("height", HEIGHT)
+ .append("g")
+ .attr("transform",
+ "translate(" + (RADIUS + 2) + "," + (RADIUS + 2) + ")");
+}
+
+function create_arc() {
+ return d3.svg.arc()
+ .outerRadius(RADIUS)
+ .innerRadius(0);
+}
+
+function create_pie(param) {
+ return d3.layout.pie()
+ .sort(null)
+ .value(function(d){ return d[param]; });
+}
+
+
+horizon.d3_pie_chart_usage = {
init: function() {
var self = this;
// Pie Charts
- var pie_chart_data = $(".d3_pie_chart");
- self.chart = d3.selectAll(".d3_pie_chart");
+ var pie_chart_data = $(".d3_pie_chart_usage");
+ self.chart = d3.selectAll(".d3_pie_chart_usage");
for (var i = 0; i < pie_chart_data.length; i++) {
var used = Math.min(parseInt($(pie_chart_data[i]).data("used")), 100);
@@ -36,79 +69,179 @@ horizon.d3_pie_chart = {
// Draw a pie chart
pieChart: function(i) {
var self = this;
- var vis = d3.select(self.chart[0][i]).append("svg:svg")
- .attr("class", "chart")
- .attr("width", self.w)
- .attr("height", self.h)
- .append("g")
- .attr("transform",
- "translate(" + (self.r + 2) + "," + (self.r + 2) + ")");
-
- var arc = d3.svg.arc()
- .outerRadius(self.r)
- .innerRadius(0);
-
- var pie = d3.layout.pie()
- .sort(null)
- .value(function(d){ return d.percentage; });
+ var vis = create_vis(self.chart[0][i]);
+ var arc = create_arc();
+ var pie = create_pie("percentage");
// Draw an empty pie chart
- var piechart = vis.selectAll(".arc")
+ vis.selectAll(".arc")
.data(pie([{"percentage":10}]))
.enter()
- .append("path")
- .attr("class","arc")
- .attr("d", arc)
- .style("fill", function(d){
- if (self.data[0].percentage >= 100) {
- return self.full;
- } else if (self.data[0].percentage >= 80) {
- return self.nearlyfull;
- } else {
- return self.frgrnd;
- }
- })
- .style("stroke", "#CCCCCC")
- .style("stroke-width", 1)
- .each(function(d) {
- self.current = d;
- return d;
- });
+ .append("path")
+ .attr("class","arc")
+ .attr("d", arc)
+ .style("fill", function(){
+ if (self.data[0].percentage >= 100) {
+ return FULL;
+ } else if (self.data[0].percentage >= 80) {
+ return NEARLY_FULL;
+ } else {
+ return FRGRND;
+ }
+ })
+ .style("stroke", STROKE)
+ .style("stroke-width", 1)
+ .each(function(d) {
+ self.current = d;
+ return d;
+ });
// Animate filling the pie chart
- animate = function(data) {
- var piechart = vis.selectAll(".arc")
+ var animate = function(data) {
+ vis.selectAll(".arc")
.data(pie(data))
.enter()
- .append("path")
- .attr("class","arc")
- .attr("d", arc)
- .style("fill", self.bkgrnd)
- .style("stroke", "#CCCCCC")
- .style("stroke-width", function(d) {
- if (self.data[0].percentage >= 100) {
- return 0;
- } else {
- return 1;
- }
- })
- .each(function(d) {
- self.current = d;
- return d;
- })
+ .append("path")
+ .attr("class","arc")
+ .attr("d", arc)
+ .style("fill", BKGRND)
+ .style("stroke", STROKE)
+ .style("stroke-width", function() {
+ if (self.data[0].percentage >= 100) {
+ return 0;
+ } else {
+ return 1;
+ }
+ })
+ .each(function(d) {
+ self.current = d;
+ return d;
+ })
.transition()
- .duration(500)
- .attrTween("d", function(a) {
- var tween = d3.interpolate(self.current, a);
- self.current = tween(0);
- return function(t) { return arc(tween(t)); };
- });
+ .duration(500)
+ .attrTween("d", function(a) {
+ var tween = d3.interpolate(self.current, a);
+ self.current = tween(0);
+ return function(t) { return arc(tween(t)); };
+ });
};
animate(self.data);
}
};
+
+horizon.d3_pie_chart_distribution = {
+ colors: d3.scale.category20(),
+
+ init: function() {
+ var self = this;
+ var pie_chart_data = $(".d3_pie_chart_distribution");
+ self.chart = d3.selectAll(".d3_pie_chart_distribution");
+
+ for (var i = 0; i < pie_chart_data.length; i++) {
+ var parts = $(pie_chart_data[i]).data("used").split("|");
+ self.data = [];
+ self.keys = [];
+ for (var j = 0; j < parts.length; j++) {
+ var key_value = parts[j].split("=");
+ var d = {};
+ d["key"] = key_value[0];
+ d["value"] = key_value[1];
+ self.data.push(d);
+ self.keys.push(key_value[0]);
+ }
+ self.pieChart(i);
+ }
+ },
+ // Draw a pie chart
+ pieChart: function(i) {
+ var self = this;
+ var vis = create_vis(self.chart[0][i]);
+ var arc = create_arc();
+ var pie = create_pie("value");
+
+ var total = 0;
+ for (var j = 0; j < self.data.length; j++) {
+ total = total + parseInt(self.data[j]["value"]);
+ }
+
+ // Draw an empty pie chart
+ vis.selectAll(".arc")
+ .data(pie([]))
+ .enter()
+ .append("path")
+ .attr("class","arc")
+ .attr("d", arc)
+ .style("stroke", STROKE)
+ .style("stroke-width", 1);
+
+ // Animate filling the pie chart
+ var animate = function(data) {
+ vis.selectAll(".arc")
+ .data(pie(data))
+ .enter()
+ .append("path")
+ .attr("class","arc")
+ .attr("d", arc)
+ .style("fill", function(d) { return self.colors(d.data.key); })
+ .style("stroke", STROKE)
+ .style("stroke-width", 1)
+ .transition()
+ .duration(500)
+ .attrTween("d", function(start) {
+ start.endAngle = start.startAngle;
+ var end = jQuery.extend({}, start);
+ end.endAngle = end.startAngle + 2 * Math.PI / total * end.value;
+ var tween = d3.interpolate(start, end);
+ return function(t) { return arc(tween(t)); };
+ });
+ };
+
+ animate(self.data);
+
+ // Add a legend
+ var legend = d3.select(self.chart[0][i])
+ .append("svg")
+ .attr("class", "legend")
+ .attr("width", WIDTH * 2)
+ .attr("height", self.data.length * 18 + 20)
+ .selectAll("g")
+ .data(self.keys)
+ .enter()
+ .append("g")
+ .attr("transform", function(d, i) {
+ return "translate(0," + i * 20 + ")";
+ });
+
+ legend.append("rect")
+ .attr("width", 18)
+ .attr("height", 18)
+ .style("fill", self.colors);
+
+ legend.append("text")
+ .attr("x", 24)
+ .attr("y", 9)
+ .attr("dy", ".35em")
+ .text(function(d) {
+ var value = 0;
+ for (var j = 0; j < self.data.length; j++) {
+ if (self.data[j]["key"] == d) {
+ value = self.data[j]["value"];
+ break;
+ }
+ }
+ return d + " " + Math.round(value/total * 100) + "%";
+ });
+ }
+};
+
+
horizon.addInitFunction(function () {
- horizon.d3_pie_chart.init();
+ horizon.d3_pie_chart_usage.init();
+});
+
+
+horizon.addInitFunction(function () {
+ horizon.d3_pie_chart_distribution.init();
});
diff --git a/horizon/templates/horizon/common/_limit_summary.html b/horizon/templates/horizon/common/_limit_summary.html
index d3fb25882e..743694ef16 100644
--- a/horizon/templates/horizon/common/_limit_summary.html
+++ b/horizon/templates/horizon/common/_limit_summary.html
@@ -3,49 +3,49 @@
{% trans "Limit Summary" %}
-
+
{% trans "Instances" %}
{% blocktrans with used=usage.limits.totalInstancesUsed|intcomma available=usage.limits.maxTotalInstances|quotainf|intcomma %}Used {{ used }} of {{ available }} {% endblocktrans %}
-
+
{% trans "VCPUs" %}
{% blocktrans with used=usage.limits.totalCoresUsed|intcomma available=usage.limits.maxTotalCores|quotainf|intcomma %}Used {{ used }} of {{ available }} {% endblocktrans %}
-
+
{% trans "RAM" %}
{% blocktrans with used=usage.limits.totalRAMUsed|mb_float_format available=usage.limits.maxTotalRAMSize|quotainf|mb_float_format %}Used {{ used }} of {{ available }} {% endblocktrans %}
-
+
{% trans "Floating IPs" %}
{% blocktrans with used=usage.limits.totalFloatingIpsUsed|intcomma available=usage.limits.maxTotalFloatingIps|quotainf|intcomma %}Used {{ used }} of {{ available }} {% endblocktrans %}
-
+
{% trans "Security Groups" %}
{% blocktrans with used=usage.limits.totalSecurityGroupsUsed|intcomma available=usage.limits.maxSecurityGroups|quotainf|intcomma%}Used {{ used }} of {{ available }} {% endblocktrans %}
{% if usage.limits.totalVolumesUsed >= 0 %}
-
+
{% trans "Volumes" %}
{% blocktrans with used=usage.limits.totalVolumesUsed|intcomma available=usage.limits.maxTotalVolumes|quotainf|intcomma %}Used {{ used }} of {{ available }} {% endblocktrans %}
-
+
{% trans "Volume Storage" %}
{% blocktrans with used=usage.limits.totalGigabytesUsed|diskgbformat available=usage.limits.maxTotalVolumeGigabytes|quotainf|diskgbformat %}Used {{ used }} of {{ available }} {% endblocktrans %}
diff --git a/openstack_dashboard/dashboards/admin/hypervisors/templates/hypervisors/index.html b/openstack_dashboard/dashboards/admin/hypervisors/templates/hypervisors/index.html
index 49b0237ccf..e590462b8f 100644
--- a/openstack_dashboard/dashboards/admin/hypervisors/templates/hypervisors/index.html
+++ b/openstack_dashboard/dashboards/admin/hypervisors/templates/hypervisors/index.html
@@ -11,21 +11,21 @@
{% trans "Hypervisor Summary" %}
-
+
{% trans "VCPU Usage" %}
{% blocktrans with used=stats.vcpus_used|intcomma available=stats.vcpus|intcomma %}Used {{ used }} of {{ available }} {% endblocktrans %}
-
+
{% trans "Memory Usage" %}
{% blocktrans with used=stats.memory_mb_used|mbformat available=stats.memory_mb|mbformat %}Used {{ used }} of {{ available }} {% endblocktrans %}
-
+
{% trans "Disk Usage" %}
{% blocktrans with used=stats.local_gb_used|diskgbformat available=stats.local_gb|diskgbformat %}Used {{ used }} of {{ available }} {% endblocktrans %}