Fix jshint errors in my updates

This commit is contained in:
Joe Fiorini
2015-01-30 10:27:01 -05:00
parent ffc12c3065
commit 2464d68b38
9 changed files with 507 additions and 513 deletions

View File

@@ -400,12 +400,12 @@ angular.module('Tower', [
templateUrl: urlPrefix + 'partials/home.html', templateUrl: urlPrefix + 'partials/home.html',
controller: 'Home', controller: 'Home',
resolve: { resolve: {
graphData: function($q, jobStatusGraphData, hostCountGraphData) { graphData: function($q, jobStatusGraphData, hostCountGraphData) {
return $q.all({ return $q.all({
jobStatus: jobStatusGraphData.get("month", "all"), jobStatus: jobStatusGraphData.get("month", "all"),
hostCounts: hostCountGraphData.get() hostCounts: hostCountGraphData.get()
}); });
} }
} }
}). }).

View File

@@ -30,7 +30,7 @@ function Home($scope, $compile, $routeParams, $rootScope, $location, $log, Wait,
ClearScope('home'); ClearScope('home');
var buttons, html, e, borderStyles, jobs_scope, schedule_scope; var buttons, html, e, borderStyles;
// Add buttons to the top of the Home page. We're using lib/ansible/generator_helpers.js-> Buttons() // Add buttons to the top of the Home page. We're using lib/ansible/generator_helpers.js-> Buttons()
// to build buttons dynamically and insure all styling and icons match the rest of the application. // to build buttons dynamically and insure all styling and icons match the rest of the application.
@@ -111,13 +111,13 @@ function Home($scope, $compile, $routeParams, $rootScope, $location, $log, Wait,
Wait('start'); Wait('start');
Rest.setUrl(GetBasePath('dashboard')); Rest.setUrl(GetBasePath('dashboard'));
Rest.get() Rest.get()
.success(function (data) { .success(function (data) {
$scope.dashboardData = data; $scope.dashboardData = data;
$scope.$emit('dashboardReady', data); $scope.$emit('dashboardReady', data);
}) })
.error(function (data, status) { .error(function (data, status) {
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard: ' + status }); ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get dashboard: ' + status });
}); });
}; };
$scope.refresh(); $scope.refresh();

View File

@@ -1,52 +1,52 @@
angular.module('DashboardGraphs') angular.module('DashboardGraphs')
.directive('autoSizeModule', ['$window', '$timeout', function($window, $timeout) { .directive('autoSizeModule', ['$window', '$timeout', function($window, $timeout) {
// Adjusts the size of the module so that all modules // Adjusts the size of the module so that all modules
// fit into a single a page; assumes there are 2 rows // fit into a single a page; assumes there are 2 rows
// of modules, with the available height being offset // of modules, with the available height being offset
// by the navbar & the count summaries module // by the navbar & the count summaries module
return function(scope, element, attr) { return function(scope, element) {
// We need to trigger a resize on the first call // We need to trigger a resize on the first call
// to this when the view things load; but we don't want // to this when the view things load; but we don't want
// to trigger a global window resize for everything that // to trigger a global window resize for everything that
// has an auto resize, since they'll all pick it up with // has an auto resize, since they'll all pick it up with
// a single call // a single call
var triggerResize = var triggerResize =
_.throttle(function() { _.throttle(function() {
$($window).resize(); $($window).resize();
}, 1000); }, 1000);
function adjustSizeInitially() { function adjustSizeInitially() {
adjustSize(); adjustSize();
triggerResize(); triggerResize();
} }
function adjustSize() { function adjustSize() {
var winHeight = $($window).height(), var winHeight = $($window).height(),
available_height = winHeight - $('#main-menu-container .navbar').outerHeight() - $('#count-container').outerHeight() - 120; available_height = winHeight - $('#main-menu-container .navbar').outerHeight() - $('#count-container').outerHeight() - 120;
element.height(available_height/2); element.height(available_height/2);
} }
$($window).resize(adjustSize); $($window).resize(adjustSize);
element.on('$destroy', function() { element.on('$destroy', function() {
$($window).off('resize', adjustSize); $($window).off('resize', adjustSize);
}); });
// Wait a second or until dashboardReady triggers, // Wait a second or until dashboardReady triggers,
// whichever comes first. The timeout handles cases // whichever comes first. The timeout handles cases
// where dashboardReady never fires. // where dashboardReady never fires.
var dashboardReadyTimeout = $timeout(adjustSizeInitially, 500); var dashboardReadyTimeout = $timeout(adjustSizeInitially, 500);
// This makes sure count-container div is loaded // This makes sure count-container div is loaded
// by controllers/Home.js before we use it // by controllers/Home.js before we use it
// to determine the available window height // to determine the available window height
scope.$on('dashboardReady', function() { scope.$on('dashboardReady', function() {
$timeout.cancel(dashboardReadyTimeout); $timeout.cancel(dashboardReadyTimeout);
adjustSizeInitially(); adjustSizeInitially();
}); });
}; };

View File

@@ -1,116 +1,126 @@
angular.module('DashboardGraphs'). angular.module('DashboardGraphs').
directive('hostCountGraph', ['GetBasePath', 'Rest', 'adjustGraphSize', '$window', function(getBasePath, Rest, adjustGraphSize, $window) { directive('hostCountGraph', ['GetBasePath', 'Rest', 'adjustGraphSize', '$window', function(getBasePath, Rest, adjustGraphSize, $window) {
return { return {
restrict: 'E', restrict: 'E',
templateUrl: '/static/partials/host_count_graph.html', templateUrl: '/static/partials/host_count_graph.html',
link: link link: link
}; };
function link(scope, element, attr) { function link(scope, element, attr) {
var url, license, license_graph; var license_graph;
scope.$watch(attr.data, function(data) { scope.$watch(attr.data, function(data) {
if(!data) return;
createGraph(data.hosts, data.license);
});
function onResize() { if(!data) {
if(!license_graph) return; return;
adjustGraphSize(license_graph, element); }
}
angular.element($window).on('resize', function(e) { createGraph(data.hosts, data.license);
if(!license_graph) return; });
adjustGraphSize(license_graph, element);
});
element.on('$destroy', function() { function onResize() {
angular.element($window).off('resize', onResize);
});
if(!license_graph) {
return;
}
adjustGraphSize(license_graph, element);
function createGraph(data, license) {
//url = getBasePath('dashboard')+'graphs/';
var graphData = [
{
"key" : "Hosts" ,
"color" : "#1778c3",
"values": data.hosts
},
{
"key" : "License" ,
"color" : "#171717",
"values": data.hosts
}
];
graphData.map(function(series) {
if(series.key==="Hosts"){
series.values = series.values.map(function(d) {
return {
x: d[0],
y: d[1]
};
});
} }
if(series.key==="License"){
series.values = series.values.map(function(d) { angular.element($window).on('resize', function() {
return {
x: d[0], if(!license_graph) {
y: license return;
}; }
});
adjustGraphSize(license_graph, element);
});
element.on('$destroy', function() {
angular.element($window).off('resize', onResize);
});
function createGraph(data, license) {
//url = getBasePath('dashboard')+'graphs/';
var graphData = [
{ "key" : "Hosts" ,
"color" : "#1778c3",
"values": data.hosts
},
{ "key" : "License" ,
"color" : "#171717",
"values": data.hosts
}
];
graphData.map(function(series) {
if(series.key==="Hosts"){
series.values = series.values.map(function(d) {
return {
x: d[0],
y: d[1]
};
});
}
if(series.key==="License"){
series.values = series.values.map(function(d) {
return {
x: d[0],
y: license
};
});
}
return series;
});
var width = $('.graph-container').width(), // nv.utils.windowSize().width/3,
height = $('.graph-container').height()*0.6; //nv.utils.windowSize().height/5,
license_graph = nv.models.lineChart()
.margin({top: 15, right: 75, bottom: 40, left: 85})
.x(function(d,i) { return i ;})
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
;
license_graph.xAxis
.axisLabel("Time")
.tickFormat(function(d) {
var dx = graphData[0].values[d] && graphData[0].values[d].x || 0;
return dx ? d3.time.format('%m/%d')(new Date(Number(dx+'000'))) : '';
});
license_graph.yAxis //Chart y-axis settings
.axisLabel('Hosts')
.tickFormat(d3.format('.f'));
d3.select(element.find('svg')[0])
.datum(graphData).transition()
.attr('width', width)
.attr('height', height)
.duration(500)
.call(license_graph)
.style({
"font-family": 'Open Sans',
"font-style": "normal",
"font-weight":400,
"src": "url(/static/fonts/OpenSans-Regular.ttf)"
});
scope.$emit('WidgetLoaded');
adjustGraphSize(license_graph, element);
return license_graph;
} }
return series;
});
var width = $('.graph-container').width(), // nv.utils.windowSize().width/3,
height = $('.graph-container').height()*0.6; //nv.utils.windowSize().height/5,
license_graph = nv.models.lineChart()
.margin({top: 15, right: 75, bottom: 40, left: 85})
.x(function(d,i) { return i ;})
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
;
license_graph.xAxis
.axisLabel("Time")
.tickFormat(function(d) {
var dx = graphData[0].values[d] && graphData[0].values[d].x || 0;
return dx ? d3.time.format('%m/%d')(new Date(Number(dx+'000'))) : '';
});
license_graph.yAxis //Chart y-axis settings
.axisLabel('Hosts')
.tickFormat(d3.format('.f'));
d3.select(element.find('svg')[0])
.datum(graphData).transition()
.attr('width', width)
.attr('height', height)
.duration(500)
.call(license_graph)
.style({
"font-family": 'Open Sans',
"font-style": "normal",
"font-weight":400,
"src": "url(/static/fonts/OpenSans-Regular.ttf)"
});
scope.$emit('WidgetLoaded');
adjustGraphSize(license_graph, element);
return license_graph;
} }
}
}]); }]);

View File

@@ -1,106 +1,102 @@
angular.module('DashboardGraphs') angular.module('DashboardGraphs')
.directive('hostStatusGraph', ['$compile', '$window', .directive('hostStatusGraph', ['$compile', '$window',
function ($compile, $window) { function ($compile, $window) {
return { return {
restrict: 'E', restrict: 'E',
link: link, link: link,
templateUrl: '/static/partials/host_status_graph.html' templateUrl: '/static/partials/host_status_graph.html'
}; };
function link(scope, element, attr) { function link(scope, element, attr) {
var html, canvas, context, winHeight, available_height, host_pie_chart; var host_pie_chart;
scope.$watch(attr.data, function(data) { scope.$watch(attr.data, function(data) {
if (data && data.hosts) { if (data && data.hosts) {
createGraph(data); createGraph(data);
} }
}); });
function adjustGraphSize() { function adjustGraphSize() {
if (angular.isUndefined(host_pie_chart)) { if (angular.isUndefined(host_pie_chart)) {
return; return;
} }
var parentHeight = element.parent().parent().height(); var parentHeight = element.parent().parent().height();
var toolbarHeight = element.find('.toolbar').height(); var toolbarHeight = element.find('.toolbar').height();
var container = element.find('svg').parent(); var container = element.find('svg').parent();
var margins = host_pie_chart.margin(); var margins = host_pie_chart.margin();
var newHeight = parentHeight - toolbarHeight - margins.bottom; var newHeight = parentHeight - toolbarHeight - margins.bottom;
$(container).height(newHeight); $(container).height(newHeight);
host_pie_chart.update(); host_pie_chart.update();
}
angular.element($window).on('resize', adjustGraphSize);
element.on('$destroy', function() {
angular.element($window).off('resize', adjustGraphSize);
});
function createGraph(data) {
if(data.hosts.total+data.hosts.failed>0){
data = [
{
"label": "Successful",
"color": "#00aa00",
"value" : data.hosts.total
} ,
{
"label": "Failed",
"color" : "#aa0000",
"value" : data.hosts.failed
} }
];
var width = $('.graph-container').width(), // nv.utils.windowSize().width/3, angular.element($window).on('resize', adjustGraphSize);
height = $('.graph-container').height()*0.7; //nv.utils.windowSize().height/5,
host_pie_chart = nv.models.pieChart()
.margin({top: 5, right: 75, bottom: 25, left: 85})
.x(function(d) { return d.label; })
.y(function(d) { return d.value; })
.showLabels(true)
.labelThreshold(0.01)
.tooltipContent(function(x, y) {
return '<b>'+x+'</b>'+ '<p>' + Math.floor(y.replace(',','')) + ' Hosts ' + '</p>';
})
.color(['#00aa00', '#aa0000']);
host_pie_chart.pie.pieLabelsOutside(true).labelType("percent"); element.on('$destroy', function() {
angular.element($window).off('resize', adjustGraphSize);
d3.select(element.find('svg')[0])
.datum(data)
.transition().duration(350)
.call(host_pie_chart)
.style({
"font-family": 'Open Sans',
"font-style": "normal",
"font-weight":400,
"src": "url(/static/fonts/OpenSans-Regular.ttf)"
}); });
adjustGraphSize(); function createGraph(data) {
return host_pie_chart; if(data.hosts.total+data.hosts.failed>0){
} data = [
else{ { "label": "Successful",
// This should go in a template or something "color": "#00aa00",
// but I'm at the end of a card and need to get this done. "value" : data.hosts.total
// We definitely need to refactor this, I'm letting } ,
// good enough be good enough for right now. { "label": "Failed",
var notFoundContainer = $('<div></div>'); "color" : "#aa0000",
notFoundContainer.css({ "value" : data.hosts.failed
'text-align': 'center', }
'width': '100%', ];
'padding-top': '2em'
});
notFoundContainer.text('No host data'); host_pie_chart = nv.models.pieChart()
.margin({top: 5, right: 75, bottom: 25, left: 85})
.x(function(d) { return d.label; })
.y(function(d) { return d.value; })
.showLabels(true)
.labelThreshold(0.01)
.tooltipContent(function(x, y) {
return '<b>'+x+'</b>'+ '<p>' + Math.floor(y.replace(',','')) + ' Hosts ' + '</p>';
})
.color(['#00aa00', '#aa0000']);
element.find('svg').replaceWith(notFoundContainer); host_pie_chart.pie.pieLabelsOutside(true).labelType("percent");
}
d3.select(element.find('svg')[0])
.datum(data)
.transition().duration(350)
.call(host_pie_chart)
.style({
"font-family": 'Open Sans',
"font-style": "normal",
"font-weight":400,
"src": "url(/static/fonts/OpenSans-Regular.ttf)"
});
adjustGraphSize();
return host_pie_chart;
}
else{
// This should go in a template or something
// but I'm at the end of a card and need to get this done.
// We definitely need to refactor this, I'm letting
// good enough be good enough for right now.
var notFoundContainer = $('<div></div>');
notFoundContainer.css({
'text-align': 'center',
'width': '100%',
'padding-top': '2em'
});
notFoundContainer.text('No host data');
element.find('svg').replaceWith(notFoundContainer);
}
}
} }
} }]);
}]);

View File

@@ -1,129 +1,120 @@
angular.module('DashboardGraphs') angular.module('DashboardGraphs')
.directive('jobStatusGraph', ['$rootScope', '$compile', '$location' , '$window', 'Wait', 'adjustGraphSize', 'jobStatusGraphData', .directive('jobStatusGraph', ['$rootScope', '$compile', '$location' , '$window', 'Wait', 'adjustGraphSize', 'jobStatusGraphData',
function ($rootScope, $compile , $location, $window, Wait, adjustGraphSize, jobStatusGraphData) { function ($rootScope, $compile , $location, $window, Wait, adjustGraphSize) {
return { return {
restrict: 'E', restrict: 'E',
templateUrl: '/static/partials/job_status_graph.html', templateUrl: '/static/partials/job_status_graph.html',
link: link link: link
}; };
function link(scope, element, attr) { function link(scope, element, attr) {
var html; var job_type, job_status_chart = nv.models.lineChart();
var url;
var job_status_chart = nv.models.lineChart();
var cleanup = angular.noop;
scope.period="month"; scope.period="month";
scope.jobType="all"; scope.jobType="all";
var data; scope.$watch(attr.data, function(value) {
scope.$watch(attr.data, function(value) { if (value) {
if (value) { createGraph(value, scope.period, scope.jobType);
createGraph(value, scope.period, scope.jobType); }
} });
});
function createGraph(data, period, jobtype){ function createGraph(data, period, jobtype){
scope.period = period; scope.period = period;
scope.jobType = jobtype; scope.jobType = jobtype;
var timeFormat, graphData = [ var timeFormat, graphData = [
{ { "color": "#00aa00",
"color": "#00aa00", "key": "Successful",
"key": "Successful", "values": data.jobs.successful
"values": data.jobs.successful },
}, { "key" : "Failed" ,
{ "color" : "#aa0000",
"key" : "Failed" , "values": data.jobs.failed
"color" : "#aa0000", }
"values": data.jobs.failed ];
if(period==="day") {
timeFormat="%H:%M";
}
else {
timeFormat = '%m/%d';
}
graphData.map(function(series) {
series.values = series.values.map(function(d) {
return {
x: d[0],
y: d[1]
};
});
return series;
});
job_status_chart
.margin({top: 5, right: 75, bottom: 40, left: 85}) //Adjust chart margins to give the x-axis some breathing room.
.x(function(d,i) { return i; })
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true); //Show the x-axis
job_status_chart.xAxis
.axisLabel("Time")//.showMaxMin(true)
.tickFormat(function(d) {
var dx = graphData[0].values[d] && graphData[0].values[d].x || 0;
return dx ? d3.time.format(timeFormat)(new Date(Number(dx+'000'))) : '';
});
job_status_chart.yAxis //Chart y-axis settings
.axisLabel('Jobs')
.tickFormat(d3.format('.f'));
d3.select(element.find('svg')[0])
.datum(graphData)
.call(job_status_chart)
.style({
"font-family": 'Open Sans',
"font-style": "normal",
"font-weight":400,
"src": "url(/static/fonts/OpenSans-Regular.ttf)"
});
// when the Period drop down filter is used, create a new graph based on the
d3.selectAll(element.find(".n"))
.on("click", function() {
period = this.getAttribute("id");
$('#period-dropdown').replaceWith("<a id=\"period-dropdown\" role=\"button\" data-toggle=\"dropdown\" data-target=\"#\" href=\"/page.html\">"+this.text+"<span class=\"caret\"><span>\n");
createGraph(data, period, job_type);
});
//On click, update with new data
d3.selectAll(element.find(".m"))
.on("click", function() {
job_type = this.getAttribute("id");
$('#type-dropdown').replaceWith("<a id=\"type-dropdown\" role=\"button\" data-toggle=\"dropdown\" data-target=\"#\" href=\"/page.html\">"+this.text+"<span class=\"caret\"><span>\n");
createGraph(data, period, job_type);
});
adjustGraphSize(job_status_chart, element);
} }
];
if(period==="day") { function onResize() {
timeFormat="%H:%M"; adjustGraphSize(job_status_chart, element);
} }
else {
timeFormat = '%m/%d'; angular.element($window).on('resize', onResize);
element.on('$destroy', function() {
angular.element($window).off('resize', onResize);
});
if (scope.removeGraphDataReady) {
scope.removeGraphDataReady();
} }
graphData.map(function(series) {
series.values = series.values.map(function(d) {
return {
x: d[0],
y: d[1]
};
});
return series;
});
job_status_chart
.margin({top: 5, right: 75, bottom: 40, left: 85}) //Adjust chart margins to give the x-axis some breathing room.
.x(function(d,i) { return i; })
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true); //Show the x-axis
var width = $('.graph-container').width(); // nv.utils.windowSize().width/3,
var height = $('.graph-container').height()*0.7; //nv.utils.windowSize().height/5,
job_status_chart.xAxis
.axisLabel("Time")//.showMaxMin(true)
.tickFormat(function(d) {
var dx = graphData[0].values[d] && graphData[0].values[d].x || 0;
return dx ? d3.time.format(timeFormat)(new Date(Number(dx+'000'))) : '';
});
job_status_chart.yAxis //Chart y-axis settings
.axisLabel('Jobs')
.tickFormat(d3.format('.f'));
d3.select(element.find('svg')[0])
.datum(graphData)
.call(job_status_chart)
.style({
"font-family": 'Open Sans',
"font-style": "normal",
"font-weight":400,
"src": "url(/static/fonts/OpenSans-Regular.ttf)"
});
// when the Period drop down filter is used, create a new graph based on the
d3.selectAll(element.find(".n"))
.on("click", function() {
period = this.getAttribute("id");
$('#period-dropdown').replaceWith("<a id=\"period-dropdown\" role=\"button\" data-toggle=\"dropdown\" data-target=\"#\" href=\"/page.html\">"+this.text+"<span class=\"caret\"><span>\n");
createGraph(data, period, job_type);
});
//On click, update with new data
d3.selectAll(element.find(".m"))
.on("click", function() {
job_type = this.getAttribute("id");
$('#type-dropdown').replaceWith("<a id=\"type-dropdown\" role=\"button\" data-toggle=\"dropdown\" data-target=\"#\" href=\"/page.html\">"+this.text+"<span class=\"caret\"><span>\n");
createGraph(data, period, job_type);
});
adjustGraphSize(job_status_chart, element);
} }
function onResize() {
adjustGraphSize(job_status_chart, element);
}
angular.element($window).on('resize', onResize);
element.on('$destroy', function() {
angular.element($window).off('resize', onResize);
});
if (scope.removeGraphDataReady) {
scope.removeGraphDataReady();
}
}
}]); }]);

View File

@@ -1,90 +1,90 @@
angular.module('DashboardGraphs'). angular.module('DashboardGraphs').
factory('adjustGraphSize', function() { factory('adjustGraphSize', function() {
// Adjusts the size of graphs based on the current height // Adjusts the size of graphs based on the current height
// of the outer parent (see auto-size-module directive). // of the outer parent (see auto-size-module directive).
// //
// Since the graph's svg element is set to width & height of 100%, // Since the graph's svg element is set to width & height of 100%,
// it will automatically size itself when the size of its container // it will automatically size itself when the size of its container
// changes. Since boxes in HTML automatically fill the width of their // changes. Since boxes in HTML automatically fill the width of their
// parent, we don't have to change the container's width. However, // parent, we don't have to change the container's width. However,
// since the makers HTML never heard of vertical rhythm, // since the makers HTML never heard of vertical rhythm,
// we have to manually set a new height on the container. // we have to manually set a new height on the container.
// //
// ## Calculating the container's new height // ## Calculating the container's new height
// //
// newHeight is the height we assign to the graph's immediate parent. // newHeight is the height we assign to the graph's immediate parent.
// This is calculated as the height of the graph-container (the // This is calculated as the height of the graph-container (the
// outer parent), offset by the height of the toolbar row // outer parent), offset by the height of the toolbar row
// (the contains the title and/or any filters) and the // (the contains the title and/or any filters) and the
// bottom margin. // bottom margin.
// //
// ## Responsive Graph Stuff // ## Responsive Graph Stuff
// //
// Letting the svg element automatically scale only solves part of // Letting the svg element automatically scale only solves part of
// the responsive graph problem. d3 draws graphs as paths, with static // the responsive graph problem. d3 draws graphs as paths, with static
// positioning of all elements. Therefore, we need to tell the graph how // positioning of all elements. Therefore, we need to tell the graph how
// to adjust itself so that it can resize properly. // to adjust itself so that it can resize properly.
// //
// ### Resizing the axes // ### Resizing the axes
// //
// First we get the width & height of the chart after it has been modified // First we get the width & height of the chart after it has been modified
// by setting the height on its parent (see Calculating the New Container's // by setting the height on its parent (see Calculating the New Container's
// Height above). Note that we need to offset the width/height by the margins // Height above). Note that we need to offset the width/height by the margins
// to make sure we keep all the spacing intact. // to make sure we keep all the spacing intact.
// //
// Next, we update the range for x & y to take the new width & height into // Next, we update the range for x & y to take the new width & height into
// account. d3 uses this range to map domain values (the actual data) onto // account. d3 uses this range to map domain values (the actual data) onto
// pixels. // pixels.
// //
// After that we adjust the number of ticks on the axes. This makes sure we // After that we adjust the number of ticks on the axes. This makes sure we
// will never have overlapping ticks. If that does become a problem, try // will never have overlapping ticks. If that does become a problem, try
// changing the divisor in the calculations to a different number until you // changing the divisor in the calculations to a different number until you
// find something that helps. For example, (width / 75) should make the x // find something that helps. For example, (width / 75) should make the x
// axis only ever display 1 tick per every 75 pixels. // axis only ever display 1 tick per every 75 pixels.
// //
// ### Redrawing the line // ### Redrawing the line
// //
// Since this is a line graph, now that we've changed the range & ticks, // Since this is a line graph, now that we've changed the range & ticks,
// we need to instruct d3 to repaint (redraw) the actual lines representing // we need to instruct d3 to repaint (redraw) the actual lines representing
// the data. We do this by setting the "d" attribute of the path element // the data. We do this by setting the "d" attribute of the path element
// that represents the line to the line function on the chart model. This // that represents the line to the line function on the chart model. This
// function triggers the mapping of domain to range, and plots the chart. // function triggers the mapping of domain to range, and plots the chart.
// Calling chartModel.update() at the end instructs nv to process our changes. // Calling chartModel.update() at the end instructs nv to process our changes.
// //
return function adjustGraphSize(chartModel, element) { return function adjustGraphSize(chartModel, element) {
var parentHeight = element.parent().parent().height(); var parentHeight = element.parent().parent().height();
var toolbarHeight = element.find('.toolbar').height(); var toolbarHeight = element.find('.toolbar').height();
var container = element.find('svg').parent(); var container = element.find('svg').parent();
var margins = chartModel.margin(); var margins = chartModel.margin();
var newHeight = parentHeight - toolbarHeight - margins.bottom; var newHeight = parentHeight - toolbarHeight - margins.bottom;
$(container).height(newHeight); $(container).height(newHeight);
var graph = d3.select(element.find('svg')[0]); var graph = d3.select(element.find('svg')[0]);
var width = parseInt(graph.style('width')) - margins.left - margins.right; var width = parseInt(graph.style('width')) - margins.left - margins.right;
var height = parseInt(graph.style('height')) - margins.top - margins.bottom; var height = parseInt(graph.style('height')) - margins.top - margins.bottom;
chartModel.xRange([0, width]); chartModel.xRange([0, width]);
chartModel.yRange([height, 0]); chartModel.yRange([height, 0]);
chartModel.xAxis.ticks(Math.max(width / 75, 2)); chartModel.xAxis.ticks(Math.max(width / 75, 2));
chartModel.yAxis.ticks(Math.max(height / 50, 2)); chartModel.yAxis.ticks(Math.max(height / 50, 2));
if (height < 160) { if (height < 160) {
graph.select('.y.nv-axis').select('.domain').style('display', 'none'); graph.select('.y.nv-axis').select('.domain').style('display', 'none');
graph.select('.y.nv-axis').select('.domain').style('display', 'initial'); graph.select('.y.nv-axis').select('.domain').style('display', 'initial');
} }
graph.select('.x.nv-axis') graph.select('.x.nv-axis')
.attr('transform', 'translate(0, ' + height + ')') .attr('transform', 'translate(0, ' + height + ')')
.call(chartModel.xAxis); .call(chartModel.xAxis);
graph.selectAll('.line') graph.selectAll('.line')
.attr('d', chartModel.lines) .attr('d', chartModel.lines);
chartModel.update(); chartModel.update();
} };
}); });

View File

@@ -1,47 +1,47 @@
angular.module('DataServices') angular.module('DataServices')
.service('hostCountGraphData', .service('hostCountGraphData',
["Rest", ["Rest",
"GetBasePath", "GetBasePath",
"ProcessErrors", "ProcessErrors",
"$q", "$q",
HostCountGraphData]); HostCountGraphData]);
function HostCountGraphData(Rest, getBasePath, processErrors, $q) { function HostCountGraphData(Rest, getBasePath, processErrors, $q) {
function pluck(property, promise) { function pluck(property, promise) {
return promise.then(function(value) { return promise.then(function(value) {
return value[property]; return value[property];
});
}
function getLicenseData() {
url = getBasePath('config');
Rest.setUrl(url);
return Rest.get()
.then(function (data){
license = data.data.license_info.instance_count;
return license;
})
}
function getHostData() {
url = getBasePath('dashboard')+'graphs/inventory/';
Rest.setUrl(url);
return pluck('data', Rest.get());
}
return {
get: function() {
return $q.all({
license: getLicenseData(),
hosts: getHostData()
}).catch(function (response) {
var errorMessage = 'Failed to get: ' + response.url + ' GET returned: ' + response.status;
processErrors(null, response.data, response.status, null, { hdr: 'Error!',
msg: errorMessage
});
return response;
}); });
} }
};
function getLicenseData() {
var url = getBasePath('config');
Rest.setUrl(url);
return Rest.get()
.then(function (data){
var license = data.data.license_info.instance_count;
return license;
});
}
function getHostData() {
var url = getBasePath('dashboard')+'graphs/inventory/';
Rest.setUrl(url);
return pluck('data', Rest.get());
}
return {
get: function() {
return $q.all({
license: getLicenseData(),
hosts: getHostData()
}).catch(function (response) {
var errorMessage = 'Failed to get: ' + response.url + ' GET returned: ' + response.status;
processErrors(null, response.data, response.status, null, { hdr: 'Error!',
msg: errorMessage
});
return response;
});
}
};
} }

View File

@@ -1,62 +1,59 @@
angular.module('DataServices') angular.module('DataServices')
.service('jobStatusGraphData', .service('jobStatusGraphData',
["Rest", ["Rest",
"GetBasePath", "GetBasePath",
"ProcessErrors", "ProcessErrors",
"$rootScope", "$rootScope",
"$q", JobStatusGraphData]);
JobStatusGraphData]);
function JobStatusGraphData(Rest, getBasePath, processErrors, $rootScope, $q) { function JobStatusGraphData(Rest, getBasePath, processErrors, $rootScope) {
var callbacks = {};
var currentCallbackId = 0;
function pluck(property, promise) { function pluck(property, promise) {
return promise.then(function(value) { return promise.then(function(value) {
return value[property]; return value[property];
}); });
} }
function getData(period, jobType) { function getData(period, jobType) {
var url = getBasePath('dashboard')+'graphs/jobs/?period='+period+'&job_type='+jobType; var url = getBasePath('dashboard')+'graphs/jobs/?period='+period+'&job_type='+jobType;
Rest.setUrl(url); Rest.setUrl(url);
var result = Rest.get() var result = Rest.get()
.catch(function(response) { .catch(function(response) {
var errorMessage = 'Failed to get: ' + response.url + ' GET returned: ' + response.status; var errorMessage = 'Failed to get: ' + response.url + ' GET returned: ' + response.status;
processErrors(null, processErrors(null,
response.data, response.data,
response.status, response.status,
null, { null, {
hdr: 'Error!', hdr: 'Error!',
msg: errorMessage msg: errorMessage
}); });
return response; return response;
}); });
return pluck('data', result); return pluck('data', result);
} }
return { return {
destroyWatcher: angular.noop, destroyWatcher: angular.noop,
setupWatcher: function(period, jobType) { setupWatcher: function(period, jobType) {
this.destroyWatcher = this.destroyWatcher =
$rootScope.$on('JobStatusChange', function() { $rootScope.$on('JobStatusChange', function() {
getData(period, jobType).then(function(result) { getData(period, jobType).then(function(result) {
$rootScope. $rootScope.
$broadcast('DataReceived:JobStatusGraph', $broadcast('DataReceived:JobStatusGraph',
result); result);
return result; return result;
}); });
}); });
}, },
get: function(period, jobType) { get: function(period, jobType) {
this.destroyWatcher(); this.destroyWatcher();
this.setupWatcher(period, jobType); this.setupWatcher(period, jobType);
return getData(period, jobType); return getData(period, jobType);
} }
}; };
} }