Merge "Pie Charts now inherit from Bootstrap Theme"

This commit is contained in:
Jenkins 2015-09-03 03:59:19 +00:00 committed by Gerrit Code Review
commit 3e5aec9d18
5 changed files with 186 additions and 102 deletions

View File

@ -16,36 +16,14 @@
</div> </div>
*/ */
// Pie chart dimensions // Pie chart SVG internal dimensions
var WIDTH = 100; var WIDTH = 100;
var HEIGHT = 100; var HEIGHT = 100;
var RADIUS = 45; var RADIUS = 45;
// Colors
var BKGRND = "#F2F2F2";
var FRGRND = "#006CCF";
var FULL = "#D0342B";
var NEARLY_FULL = "#FFA500";
var STROKE_USAGE = "#CCCCCC";
var STROKE_DISTRIBUTION = "#609ED2";
var BLUE_SHADES = [
"#609ED2",
"#BFD8ED",
"#EFF5FB",
"#2D6997",
"#1F4A6F",
"#122A40",
"#428BCA",
"#90BAE0",
"#DFEBF6"
];
function create_vis(chart) { function create_vis(chart) {
return d3.select(chart).append("svg:svg") return d3.select(chart).append("svg:svg")
.attr("class", "chart") .attr("class", "chart pie-chart")
.attr("width", WIDTH)
.attr("height", HEIGHT)
.attr("viewBox", "0 0 " + WIDTH + " " + HEIGHT ) .attr("viewBox", "0 0 " + WIDTH + " " + HEIGHT )
.append("g") .append("g")
.attr("transform", .attr("transform",
@ -99,10 +77,7 @@ horizon.d3_pie_chart_usage = {
.enter() .enter()
.append("path") .append("path")
.attr("class","arc") .attr("class","arc")
.attr("d", arc) .attr("d", arc);
.style("fill", BKGRND)
.style("stroke", STROKE_USAGE)
.style("stroke-width", 1);
// Animate filling the pie chart // Animate filling the pie chart
var animate = function(data) { var animate = function(data) {
@ -110,25 +85,16 @@ horizon.d3_pie_chart_usage = {
.data(pie(data)) .data(pie(data))
.enter() .enter()
.append("path") .append("path")
.attr("class","arc") .attr("class", function() {
.attr("d", arc) var ret_val = "arc inner";
.style("fill", function(){
if (self.data[0].percentage >= 100) { if (self.data[0].percentage >= 100) {
return FULL; ret_val += " FULL";
} else if (self.data[0].percentage >= 80) { } else if (self.data[0].percentage >= 80) {
return NEARLY_FULL; ret_val += " NEARLY_FULL";
} else {
return FRGRND;
}
})
.style("stroke", STROKE_USAGE)
.style("stroke-width", function() {
if (self.data[0].percentage <= 0 || self.data[0].percentage >= 100) {
return 0;
} else {
return 1;
} }
return ret_val;
}) })
.attr("d", arc)
.transition() .transition()
.duration(500) .duration(500)
.attrTween("d", function(start) { .attrTween("d", function(start) {
@ -144,8 +110,7 @@ horizon.d3_pie_chart_usage = {
var show_numbers = function() { var show_numbers = function() {
vis.append("text") vis.append("text")
.style("fill", "black") .attr("class", "chart-numbers")
.style("font-size","28px")
.attr('text-anchor', 'middle') .attr('text-anchor', 'middle')
.attr('dominant-baseline', 'central') .attr('dominant-baseline', 'central')
.text(self.data); .text(self.data);
@ -154,6 +119,10 @@ horizon.d3_pie_chart_usage = {
if (fill) { if (fill) {
animate(self.data); animate(self.data);
} else { } else {
// TODO: this seems to be very broken...
// https://bugs.launchpad.net/horizon/+bug/1490787
// It prints: [object Object] to the screen
show_numbers(self.data); show_numbers(self.data);
} }
} }
@ -161,8 +130,6 @@ horizon.d3_pie_chart_usage = {
horizon.d3_pie_chart_distribution = { horizon.d3_pie_chart_distribution = {
colors: BLUE_SHADES,
init: function() { init: function() {
var self = this; var self = this;
var pie_chart_data = $(".d3_pie_chart_distribution"); var pie_chart_data = $(".d3_pie_chart_distribution");
@ -181,11 +148,11 @@ horizon.d3_pie_chart_distribution = {
self.data.push(d); self.data.push(d);
self.keys.push(key_value[0]); self.keys.push(key_value[0]);
} }
self.pieChart(i); self.pieChart(i, $(pie_chart_data[i]));
} }
}, },
// Draw a pie chart // Draw a pie chart
pieChart: function(i) { pieChart: function(i, $elem) {
var self = this; var self = this;
var vis = create_vis(self.chart[0][i]); var vis = create_vis(self.chart[0][i]);
var arc = create_arc(); var arc = create_arc();
@ -207,10 +174,7 @@ horizon.d3_pie_chart_distribution = {
.enter() .enter()
.append("path") .append("path")
.attr("class","arc") .attr("class","arc")
.attr("d", arc) .attr("d", arc);
.style("fill", BKGRND)
.style("stroke", STROKE_DISTRIBUTION)
.style("stroke-width", 1);
// Animate filling the pie chart // Animate filling the pie chart
var animate = function(data) { var animate = function(data) {
@ -218,13 +182,8 @@ horizon.d3_pie_chart_distribution = {
.data(pie(data)) .data(pie(data))
.enter() .enter()
.append("path") .append("path")
.attr("class","arc") .attr("class","arc inner")
.attr("d", arc) .attr("d", arc)
.style("fill", function(d) {
return self.colors[self.data.indexOf(d.data)];
})
.style("stroke", STROKE_DISTRIBUTION)
.style("stroke-width", 1)
.transition() .transition()
.duration(500) .duration(500)
.attrTween("d", function(start) { .attrTween("d", function(start) {
@ -240,51 +199,50 @@ horizon.d3_pie_chart_distribution = {
animate(self.data); animate(self.data);
} }
// Add a legend // The legend actually doesn't need to be an SVG element at all
var legend = d3.select(self.chart[0][i]) // By making it standard markup, we can allow greater customization
.append("svg") var $legend = $(document.createElement('div')).addClass('legend');
.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") // This loop might seem wasteful, but we need to determine the total for the label
.attr("width", 18) var total = 0;
.attr("height", 18) for (var j = 0; j < self.data.length; j++) {
.style("fill", function(d) {
var item;
for (var i = 0; i < self.data.length; i++) {
if (self.data[i].key == d) {
item = self.data[i];
break;
}
}
return self.colors[self.data.indexOf(item)];
});
legend.append("text") // We need to use it as a float again later, convert it now and store ... its faster
.attr("x", 24) self.data[j].value = parseFloat(self.data[j].value);
.attr("y", 9) total += self.data[j].value;
.attr("dy", ".35em") }
.text(function(d) {
if (total === 0) { for (var j = 0; j < self.data.length; j++) {
return d + " 0%"; var this_item = self.data[j];
} var $this_group = $(document.createElement('div'))
var value = 0; .addClass('legend-group')
for (var j = 0; j < self.data.length; j++) { .appendTo($legend);
if (self.data[j].key == d) {
value = self.data[j].value; $(document.createElement('span'))
break; .addClass('legend-symbol')
} .appendTo($this_group);
}
return d + " " + Math.round(value/total * 100) + "%"; $(document.createElement('span'))
}); .addClass('legend-key')
.text(this_item.key)
.appendTo($this_group);
var $this_value = $(document.createElement('span'))
.addClass('legend-value');
// If its zero, then we don't need to Math it.
if (this_item.value === 0) {
$this_item.text("0%");
} else {
$this_value.text(Math.round((this_item.value/total) * 100) + "%");
}
// Append it to the container
$this_value.appendTo($this_group);
}
// Append the container last ... cause its faster
$elem.append($legend);
} }
}; };

View File

@ -0,0 +1,112 @@
// General Pie Chart Styles
// The idea behind this mixin in to allow a variety of
// colors to be configured, from 1 - $num, that will
// toggle between an incrementing percentage ($increment)
// from the theme's primary brand color. This should
// adapt nicely to most themes.
@mixin make_pie_chart_distribution($num, $increment) {
@for $ii from 1 through $num {
$color_increment: $increment * ($ii/2);
// Set the arc color
.arc:nth-child(#{$ii}n) {
@if $ii % 2 == 0 {
fill: lighten($brand-primary, $color_increment * 1%);
} @else {
fill: darken($brand-primary, $color_increment * 1%);
}
}
// Set the corresponding legend symbol
.legend-group:nth-child(#{$ii}n) .legend-symbol {
@if $ii % 2 == 0 {
color: lighten($brand-primary, $color_increment * 1%);
} @else {
color: darken($brand-primary, $color_increment * 1%);
}
}
}
}
// This is who sets the size of the pie chart
.pie-chart {
width: $font-size-h1*3;
height: $font-size-h1*3;
// The container arc's color and stroke
.arc {
fill: $table-border-color;
stroke-width: 1px;
}
}
// Chart Usage Specifics
.d3_pie_chart_usage {
.arc {
stroke: $table-border-color;
}
// The inner arc
.arc.inner {
fill: $brand-primary;
stroke: none;
// Specialness if its full
&.FULL {
fill: $brand-danger;
}
// Specialness if its almost full
&.NEARLY_FULL {
fill: $brand-warning;
}
}
}
// Chart Distribution Specifics
.d3_pie_chart_distribution {
// The container arc's color and stroke
.arc {
stroke: $brand-primary;
}
// Set the colors!
@include make_pie_chart_distribution(8, 8);
.legend {
padding: $padding-base-horizontal $padding-base-vertical;
text-align: left;
}
.legend-group {
padding: $padding-xs-horizontal $padding-small-vertical;
}
.legend-symbol {
@extend .fa;
@extend .fa-square;
font-size: $font-size-h3;
padding-right: $padding-small-vertical;
}
.legend-symbol,
.legend-key,
.legend-value {
display: inline-block;
line-height: $line-height-computed;
vertical-align: middle;
}
.legend-key {
padding-right: $padding-small-vertical;
}
}
.chart-numbers {
fill: $gray-dark;
font-size: $font-size-h3;
}

View File

@ -22,6 +22,7 @@
@import "components/workflow"; @import "components/workflow";
@import "components/network_topology"; @import "components/network_topology";
@import "components/context_selection"; @import "components/context_selection";
@import "components/pie_charts";
@import "/framework/framework"; @import "/framework/framework";

View File

@ -2,6 +2,7 @@
@import 'components/_context_selection'; @import 'components/_context_selection';
@import 'components/sidebar'; @import 'components/sidebar';
@import 'components/pie_charts';
.navbar-brand { .navbar-brand {

View File

@ -0,0 +1,12 @@
.d3_pie_chart_usage {
.arc {
stroke: $gray-light;
fill: $gray-lighter;
}
}
.d3_pie_chart_distribution {
.legend-group {
padding: 1px $padding-small-vertical;
}
}