kubernetes/www/master/components/dashboard/js/modules/directives/d3MinionBarGauge.js
BC Broussard 2f43fc72db Update Web UI Bar Gauge Graphs
- Changed file system abbreviation from 'FS' to Filesystem
- Made chart height dynamic and incorporated legend height change into the master code/datafile.go binary
- Updated the max colors for the graph
- Realigned graph numbers
2015-06-26 13:52:08 -07:00

346 lines
15 KiB
JavaScript

(function() {
'use strict';
angular.module('kubernetesApp.components.dashboard')
.directive('d3MinionBarGauge', [
'd3DashboardService',
function(d3DashboardService) {
return {
restrict: 'E',
scope: {
data: '=',
thickness: '@',
graphWidth: '@',
graphHeight: '@'
},
link: function(scope, element, attrs) {
var draw = function(d3) {
var svg = d3.select("svg.chart");
var legendSvg = d3.select("svg.legend");
window.onresize = function() { return scope.$apply(); };
scope.$watch(function() { return angular.element(window)[0].innerWidth; },
function() { return scope.render(scope.data); });
scope.$watch('data', function(newVals, oldVals) {
return initOrUpdate(newVals, oldVals);
}, true);
function initOrUpdate(newVals, oldVals) {
if (oldVals === null || oldVals === undefined) {
return scope.render(newVals);
} else {
return update(oldVals, newVals);
}
}
var textOffset = 10;
var el = null;
var radius = 100;
var oldData = [];
function init(options) {
var clone = options.data;
var preparedData = setData(clone);
setup(preparedData, options.width, options.height);
}
function setup(data, w, h) {
svg = d3.select(element[0]).append("svg").attr("width", "100%");
legendSvg = d3.select(element[0]).append("svg").attr("width", "100%");
var chart = svg.attr("class", "chart")
.attr("width", w)
.attr("height", h - 25)
.append("svg:g")
.attr("class", "concentricchart")
.attr("transform", "translate(" + ((w / 2)) + "," + h / 4 + ")");
var legend = legendSvg.attr("class", "legend").attr("width", w);
radius = Math.min(w, h) / 2;
var hostName = legendSvg.append("text")
.attr("class", "hostName")
.attr("transform", "translate(" + ((w - 120) / 2) + "," + 15 + ")");
var label_legend_area = legendSvg.append("svg:g")
.attr("class", "label_legend_area")
.attr("transform", "translate(" + ((w - 215) / 2) + "," + 35 + ")");
var legend_group = label_legend_area.append("svg:g").attr("class", "legend_group");
var label_group = label_legend_area.append("svg:g")
.attr("class", "label_group")
.attr("transform", "translate(" + 25 + "," + 11 + ")");
var stats_group = label_legend_area.append("svg:g")
.attr("class", "stats_group")
.attr("transform", "translate(" + 115 + "," + 11 + ")");
var path_group = chart.append("svg:g")
.attr("class", "path_group")
.attr("transform", "translate(0," + (h / 4) + ")");
var value_group = chart.append("svg:g")
.attr("class", "value_group")
.attr("transform", "translate(" + -(w * 0.205) + "," + -(h * 0.10) + ")");
generateArcs(chart, data);
}
function update(_oldData, _newData) {
if (_newData === undefined || _newData === null) {
return;
}
var clone = jQuery.extend(true, {}, _newData);
var cloneOld = jQuery.extend(true, {}, _oldData);
var preparedData = setData(clone);
oldData = setData(cloneOld);
animate(preparedData);
}
function animate(data) { generateArcs(null, data); }
function setData(data) {
var diameter = 2 * Math.PI * radius;
var localData = [];
$.each(data[0].segments, function(ri, value) {
function calcAngles(v) {
var segmentValueSum = 200;
if (v > segmentValueSum) {
v = segmentValueSum;
}
var segmentValue = v;
var fraction = segmentValue / segmentValueSum;
var arcBatchLength = fraction * 4 * Math.PI;
var arcPartition = arcBatchLength;
var startAngle = Math.PI * 2;
var endAngle = startAngle + arcPartition;
return {
startAngle: startAngle,
endAngle: endAngle
};
}
var valueData = calcAngles(value.value);
data[0].segments[ri].startAngle = valueData.startAngle;
data[0].segments[ri].endAngle = valueData.endAngle;
var maxData = value.maxData;
var maxTickData = calcAngles(maxData.maxValue + 0.2);
data[0].segments[ri].maxTickStartAngle = maxTickData.startAngle;
data[0].segments[ri].maxTickEndAngle = maxTickData.endAngle;
var maxArcData = calcAngles(maxData.maxValue);
data[0].segments[ri].maxArcStartAngle = maxArcData.startAngle;
data[0].segments[ri].maxArcEndAngle = maxArcData.endAngle;
data[0].segments[ri].index = ri;
});
localData.push(data[0].segments);
return localData[0];
}
function generateArcs(_svg, data) {
var chart = svg;
var transitionTime = 750;
$.each(data, function(index, value) {
if (oldData[index] !== undefined) {
data[index].previousEndAngle = oldData[index].endAngle;
} else {
data[index].previousEndAngle = 0;
}
});
var thickness = parseInt(scope.thickness, 10);
var ir = (parseInt(scope.graphWidth, 10) / 3);
var path_group = svg.select('.path_group');
var arc_group = path_group.selectAll(".arc_group").data(data);
var arcEnter = arc_group.enter().append("g").attr("class", "arc_group");
arcEnter.append("path").attr("class", "bg-circle").attr("d", getBackgroundArc(thickness, ir));
arcEnter.append("path")
.attr("class", function(d, i) { return 'max_tick_arc ' + d.maxData.maxTickClassNames; });
arcEnter.append("path")
.attr("class", function(d, i) { return 'max_bg_arc ' + d.maxData.maxClassNames; });
arcEnter.append("path").attr("class", function(d, i) { return 'value_arc ' + d.classNames; });
var max_tick_arc = arc_group.select(".max_tick_arc");
max_tick_arc.transition()
.attr("class", function(d, i) { return 'max_tick_arc ' + d.maxData.maxTickClassNames; })
.attr("d", function(d) {
var arc = maxArc(thickness, ir);
arc.startAngle(d.maxTickStartAngle);
arc.endAngle(d.maxTickEndAngle);
return arc(d);
});
var max_bg_arc = arc_group.select(".max_bg_arc");
max_bg_arc.transition()
.attr("class", function(d, i) { return 'max_bg_arc ' + d.maxData.maxClassNames; })
.attr("d", function(d) {
var arc = maxArc(thickness, ir);
arc.startAngle(d.maxArcStartAngle);
arc.endAngle(d.maxArcEndAngle);
return arc(d);
});
var value_arc = arc_group.select(".value_arc");
value_arc.transition().ease("exp").attr("class", function(d, i) {
return 'value_arc ' + d.classNames;
}).duration(transitionTime).attrTween("d", function(d) { return arcTween(d, thickness, ir); });
arc_group.exit()
.select(".value_arc")
.transition()
.ease("exp")
.duration(transitionTime)
.attrTween("d", function(d) { return arcTween(d, thickness, ir); })
.remove();
drawLabels(chart, data, ir, thickness);
buildLegend(chart, data);
}
function arcTween(b, thickness, ir) {
var prev = JSON.parse(JSON.stringify(b));
prev.endAngle = b.previousEndAngle;
var i = d3.interpolate(prev, b);
return function(t) { return getArc(thickness, ir)(i(t)); };
}
function maxArc(thickness, ir) {
var arc = d3.svg.arc().innerRadius(function(d) {
return getRadiusRing(ir, d.index);
}).outerRadius(function(d) { return getRadiusRing(ir + thickness, d.index); });
return arc;
}
function drawLabels(chart, data, ir, thickness) {
svg.select('.value_group').selectAll("*").remove();
var counts = data.length;
var value_group = chart.select('.value_group');
var valueLabels = value_group.selectAll("text.value").data(data);
valueLabels.enter()
.append("svg:text")
.attr("class", "value")
.attr("dx", function(d, i) { return 68; })
.attr("dy", function(d, i) { return (thickness + 3) * i; })
.attr("text-anchor", function(d) { return "start"; })
.text(function(d) { return d.value; });
valueLabels.transition().duration(300).attrTween(
"d", function(d) { return arcTween(d, thickness, ir); });
valueLabels.exit().remove();
}
function buildLegend(chart, data) {
var svg = legendSvg;
svg.select('.label_group').selectAll("*").remove();
svg.select('.legend_group').selectAll("*").remove();
svg.select('.stats_group').selectAll("*").remove();
var host_name = svg.select('.hostName');
var label_group = svg.select('.label_group');
var stats_group = svg.select('.stats_group');
host_name.text(data[0].hostName);
host_name = svg.selectAll("text.hostName").data(data);
host_name.attr("text-anchor", function(d) { return "start"; })
.text(function(d) { return d.hostName; });
host_name.exit().remove();
var labels = label_group.selectAll("text.labels").data(data);
labels.enter()
.append("svg:text")
.attr("class", "labels")
.attr("dy", function(d, i) { return 19 * i; })
.attr("text-anchor", function(d) { return "start"; })
.text(function(d) { return d.label; });
labels.exit().remove();
var stats = stats_group.selectAll("text.stats").data(data);
stats.enter()
.append("svg:text")
.attr("class", "stats")
.attr("dy", function(d, i) { return 19 * i; })
.attr("text-anchor", function(d) { return "start"; })
.text(function(d) { return d.stats; });
stats.exit().remove();
var legend_group = svg.select('.legend_group');
var legend = legend_group.selectAll("rect").data(data);
legend.enter()
.append("svg:rect")
.attr("x", 2)
.attr("y", function(d, i) { return 19 * i; })
.attr("width", 13)
.attr("height", 13)
.attr("class", function(d, i) { return "rect " + d.classNames; });
legend.exit().remove();
}
function getRadiusRing(ir, i) { return ir - (i * 20); }
function getArc(thickness, ir) {
var arc = d3.svg.arc()
.innerRadius(function(d) { return getRadiusRing(ir, d.index); })
.outerRadius(function(d) { return getRadiusRing(ir + thickness, d.index); })
.startAngle(function(d, i) { return d.startAngle; })
.endAngle(function(d, i) { return d.endAngle; });
return arc;
}
function getBackgroundArc(thickness, ir) {
var arc = d3.svg.arc()
.innerRadius(function(d) { return getRadiusRing(ir, d.index); })
.outerRadius(function(d) { return getRadiusRing(ir + thickness, d.index); })
.startAngle(0)
.endAngle(function() { return 2 * Math.PI; });
return arc;
}
scope.render = function(data) {
if (data === undefined || data === null) {
return;
}
d3.select(element[0]).select("svg.chart").remove();
d3.select(element[0]).select("svg.legend").remove();
var graph = $(element[0]);
var w = scope.graphWidth;
var h = scope.graphHeight;
var options = {
data: data,
width: w,
height: h
};
init(options);
};
};
d3DashboardService.d3().then(draw);
}
};
}
]);
}());