Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular infra dashboards #1901

Merged
merged 18 commits into from Oct 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,18 @@
angular.module( 'patternfly.card' ).component('pfAggregateStatusCard', {
bindings: {
status: '=',
showTopBorder: '@?',
altLayout: '@?',
layout: '@?',
},
templateUrl: '/static/pf_charts/aggregate-status-card.html.haml',
controller: function() {
'use strict';
var vm = this;
vm.$onInit = function() {
vm.shouldShowTopBorder = (vm.showTopBorder === 'true');
vm.isAltLayout = (vm.altLayout === 'true' || vm.layout === 'tall');
vm.isMiniLayout = (vm.layout === 'mini');
};
},
});
@@ -0,0 +1,51 @@
angular.module('patternfly.charts').component('pfC3Chart', {
bindings: {
config: '<',
getChartCallback: '<',
},
template: '<div id=""></div>',
controller: c3ChartController,
});
c3ChartController.$inject = ['$timeout', '$attrs'];

function c3ChartController($timeout, $attrs) {
var vm = this;
var prevConfig;

// store the chart object
var chart;
vm.generateChart = function() {
var chartData;

// Need to deep watch changes in chart config
prevConfig = angular.copy(vm.config);

$timeout(function() {
chartData = vm.config;
if (chartData) {
chartData.bindto = '#' + $attrs.id;
// only re-generate donut pct chart if it has a threshold object
// because it's colors will change based on data and thresholds
if (! chart || ($attrs.id.indexOf('donutPctChart') !== -1 && chartData.thresholds)) {
chart = c3.generate(chartData);
} else {
// if chart is already created, then we only need to re-load data
chart.load(vm.config.data);
}
if (vm.getChartCallback) {
vm.getChartCallback(chart);
}
prevConfig = angular.copy(vm.config);
}
});
};

vm.$doCheck = function() {
// do a deep compare on config
if (! angular.equals(vm.config, prevConfig)) {
vm.generateChart();
}
};
}


118 changes: 118 additions & 0 deletions app/assets/javascripts/components/pf_charts/donut-chart.component.js
@@ -0,0 +1,118 @@
/* global patternfly */
angular.module('patternfly.charts').component('pfDonutChart', {
bindings: {
config: '<',
data: '<',
chartHeight: '<?',
},
templateUrl: '/static/pf_charts/donut-chart.html.haml',
controller: donutChartController,
});
donutChartController.$inject = ['pfUtils'];

function donutChartController(pfUtils) {
'use strict';
var vm = this;
var prevData;

vm.$onInit = function() {
vm.donutChartId = 'donutChart';
if (vm.config.chartId) {
vm.donutChartId = vm.config.chartId + vm.donutChartId;
}

vm.updateAll();
};

vm.getDonutData = function() {
return {
type: 'donut',
columns: vm.data,
order: null,
colors: vm.config.colors,
};
};

vm.updateAll = function() {
// Need to deep watch changes in chart data
prevData = angular.copy(vm.data);

vm.config = pfUtils.merge(patternfly.c3ChartDefaults().getDefaultDonutConfig(), vm.config);
vm.config.tooltip = { contents: patternfly.pfDonutTooltipContents };
vm.config.data = vm.getDonutData();
vm.config.data.onclick = vm.config.onClickFn;
};

vm.getTotal = function() {
var total = 0;
angular.forEach(vm.data, function(value) {
angular.forEach(value, function(innerValue) {
if (! isNaN(innerValue)) {
total += Number(innerValue);
}
});
});
return total;
};

vm.getCenterLabelText = function() {
var centerLabelText;

// default
centerLabelText = { bigText: vm.getTotal(),
smText: vm.config.donut.title};

if (vm.config.centerLabelFn) {
centerLabelText.bigText = vm.config.centerLabelFn();
centerLabelText.smText = '';
}

return centerLabelText;
};

vm.setupDonutChartTitle = function() {
var donutChartTitle;
var centerLabelText;

if (angular.isUndefined(vm.chart)) {
return;
}

donutChartTitle = d3.select(vm.chart.element).select('text.c3-chart-arcs-title');
if (! donutChartTitle) {
return;
}

centerLabelText = vm.getCenterLabelText();

// Remove any existing title.
donutChartTitle.text('');
if (centerLabelText.bigText && ! centerLabelText.smText) {
donutChartTitle.text(centerLabelText.bigText);
} else {
donutChartTitle.insert('tspan').text(centerLabelText.bigText).classed('donut-title-big-pf', true).attr('dy', 0).attr('x', 0);
donutChartTitle.insert('tspan').text(centerLabelText.smText).classed('donut-title-small-pf', true).attr('dy', 20).attr('x', 0);
}
};

vm.setChart = function(chart) {
vm.chart = chart;
vm.setupDonutChartTitle();
};

vm.$onChanges = function(changesObj) {
if (changesObj.config || changesObj.data) {
vm.updateAll();
}
if (changesObj.chartHeight) {
vm.config.size.height = changesObj.chartHeight.currentValue;
}
};

vm.$doCheck = function() {
// do a deep compare on data
if (! angular.equals(vm.data, prevData)) {
vm.updateAll();
}
};
}
@@ -0,0 +1,191 @@
/* global patternfly */
angular.module('patternfly.charts').component('pfDonutPctChart', {
bindings: {
config: '<',
data: '<',
chartHeight: '<?',
centerLabel: '<?',
onThresholdChange: '&',
},
templateUrl: '/static/pf_charts/donut-pct-chart.html.haml',
controller: donutPctChartController,
});
donutPctChartController.$inject = ['pfUtils'];

function donutPctChartController(pfUtils) {
'use strict';
var vm = this;
var prevData;

vm.$onInit = function() {
vm.donutChartId = 'donutPctChart';
if (vm.config.chartId) {
vm.donutChartId = vm.config.chartId + vm.donutChartId;
}

vm.updateAll();
};

vm.updateAvailable = function() {
vm.data.available = vm.data.total - vm.data.used;
};

vm.getStatusColor = function(used, thresholds) {
var threshold = "none";
var color = pfUtils.colorPalette.blue;

if (thresholds) {
threshold = "ok";
color = pfUtils.colorPalette.green;
if (used >= thresholds.error) {
threshold = "error";
color = pfUtils.colorPalette.red;
} else if (used >= thresholds.warning) {
threshold = "warning";
color = pfUtils.colorPalette.orange;
}
}

if (! vm.threshold || vm.threshold !== threshold) {
vm.threshold = threshold;
vm.onThresholdChange({ threshold: vm.threshold });
}

return color;
};

vm.statusDonutColor = function() {
var color;
var percentUsed;

color = { pattern: [] };
percentUsed = vm.data.used / vm.data.total * 100.0;
color.pattern[0] = vm.getStatusColor(percentUsed, vm.config.thresholds);
color.pattern[1] = pfUtils.colorPalette.black300;
return color;
};

vm.donutTooltip = function() {
return {
contents: function(d) {
var tooltipHtml;

if (vm.config.tooltipFn) {
tooltipHtml = '<span class="donut-tooltip-pf" style="white-space: nowrap;">' +
vm.config.tooltipFn(d) +
'</span>';
} else {
tooltipHtml = '<span class="donut-tooltip-pf" style="white-space: nowrap;">' +
Math.round(d[0].ratio * 100) + '%' + ' ' + vm.config.units + ' ' + d[0].name +
'</span>';
}

return tooltipHtml;
},
};
};

vm.getDonutData = function() {
return {
columns: [
['Used', vm.data.used],
['Available', vm.data.available],
],
type: 'donut',
donut: {
label: {
show: false,
},
},
groups: [
['used', 'available'],
],
order: null,
};
};

vm.getCenterLabelText = function() {
var centerLabelText;

// default to 'used' info.
centerLabelText = { bigText: vm.data.used,
smText: vm.config.units + ' Used' };

if (vm.config.centerLabelFn) {
centerLabelText.bigText = vm.config.centerLabelFn();
centerLabelText.smText = '';
} else if (vm.centerLabel === 'none') {
centerLabelText.bigText = '';
centerLabelText.smText = '';
} else if (vm.centerLabel === 'available') {
centerLabelText.bigText = vm.data.available;
centerLabelText.smText = vm.config.units + ' Available';
} else if (vm.centerLabel === 'percent') {
centerLabelText.bigText = Math.round(vm.data.used / vm.data.total * 100.0) + '%';
centerLabelText.smText = 'of ' + vm.data.total + ' ' + vm.config.units;
}

return centerLabelText;
};

vm.updateAll = function() {
// Need to deep watch changes in chart data
prevData = angular.copy(vm.data);

vm.config = pfUtils.merge(patternfly.c3ChartDefaults().getDefaultDonutConfig(), vm.config);
vm.updateAvailable();
vm.config.data = pfUtils.merge(vm.config.data, vm.getDonutData());
vm.config.color = vm.statusDonutColor(vm);
vm.config.tooltip = vm.donutTooltip();
vm.config.data.onclick = vm.config.onClickFn;
};

vm.setupDonutChartTitle = function() {
var donutChartTitle;
var centerLabelText;

if (angular.isUndefined(vm.chart)) {
return;
}

donutChartTitle = d3.select(vm.chart.element).select('text.c3-chart-arcs-title');
if (! donutChartTitle) {
return;
}

centerLabelText = vm.getCenterLabelText();

// Remove any existing title.
donutChartTitle.selectAll('*').remove();
if (centerLabelText.bigText && ! centerLabelText.smText) {
donutChartTitle.text(centerLabelText.bigText);
} else {
donutChartTitle.insert('tspan').text(centerLabelText.bigText).classed('donut-title-big-pf', true).attr('dy', 0).attr('x', 0);
donutChartTitle.insert('tspan').text(centerLabelText.smText).classed('donut-title-small-pf', true).attr('dy', 20).attr('x', 0);
}
};

vm.setChart = function(chart) {
vm.chart = chart;
vm.setupDonutChartTitle();
};

vm.$onChanges = function(changesObj) {
if (changesObj.config || changesObj.data) {
vm.updateAll();
}
if (changesObj.chartHeight) {
vm.config.size.height = changesObj.chartHeight.currentValue;
}
if (changesObj.centerLabel) {
vm.setupDonutChartTitle();
}
};

vm.$doCheck = function() {
// do a deep compare on data
if (! angular.equals(vm.data, prevData)) {
vm.updateAll();
}
};
}