Merge "JSCS cleanup - style guide cleanup for charts"
This commit is contained in:
commit
1611cba86f
@ -76,7 +76,7 @@ module.exports = function(config) {
|
||||
'framework/framework.module.js',
|
||||
'framework/util/util.module.js',
|
||||
'framework/util/tech-debt/tech-debt.module.js',
|
||||
'framework/widgets/charts/charts.js',
|
||||
'framework/widgets/charts/charts.module.js',
|
||||
'framework/widgets/metadata-tree/metadata-tree.js',
|
||||
'framework/widgets/modal/modal.module.js',
|
||||
'framework/widgets/table/table.js',
|
||||
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name horizon.framework.widgets.charts.directive:chartTooltip
|
||||
* @element
|
||||
* @param {object} tooltip-data The tooltip data model and styles
|
||||
* @description
|
||||
* The `chartTooltip` directive renders a tooltip showing a colored
|
||||
* icon, label, and value.
|
||||
*
|
||||
* Data Model and Styles:
|
||||
* ```
|
||||
* var tooltipData = {
|
||||
* enabled: true,
|
||||
* label: 'Applied',
|
||||
* value: 1,
|
||||
* icon: 'fa-square',
|
||||
* iconColor: '#333333',
|
||||
* iconClass: 'warning',
|
||||
* style: { left: '10px', top: '10px' }
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @restrict E
|
||||
* @scope tooltip: '=tooltipData'
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* <chart-tooltip tooltip-data='tooltipData'></chart-tooltip>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
angular
|
||||
.module('horizon.framework.widgets.charts')
|
||||
.directive('chartTooltip', chartTooltip);
|
||||
|
||||
chartTooltip.$inject = ['horizon.framework.widgets.basePath'];
|
||||
|
||||
function chartTooltip(path) {
|
||||
var directive = {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
tooltip: '=tooltipData'
|
||||
},
|
||||
templateUrl: path + 'charts/chart-tooltip.html'
|
||||
};
|
||||
|
||||
return directive;
|
||||
}
|
||||
})();
|
@ -1,47 +0,0 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular.module('horizon.framework.widgets.charts')
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name horizon.framework.widgets.charts.directive:chartTooltip
|
||||
* @element
|
||||
* @param {object} tooltip-data The tooltip data model and styles
|
||||
* @description
|
||||
* The `chartTooltip` directive renders a tooltip showing a colored
|
||||
* icon, label, and value.
|
||||
*
|
||||
* Data Model and Styles:
|
||||
* ```
|
||||
* var tooltipData = {
|
||||
* enabled: true,
|
||||
* label: 'Applied',
|
||||
* value: 1,
|
||||
* icon: 'fa-square',
|
||||
* iconColor: '#333333',
|
||||
* iconClass: 'warning',
|
||||
* style: { left: '10px', top: '10px' }
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @restrict E
|
||||
* @scope tooltip: '=tooltipData'
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* <chart-tooltip tooltip-data='tooltipData'></chart-tooltip>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
.directive('chartTooltip', [ 'horizon.framework.widgets.basePath', function (path) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
tooltip: '=tooltipData'
|
||||
},
|
||||
templateUrl: path + 'charts/chart-tooltip.html'
|
||||
};
|
||||
}]);
|
||||
|
||||
})();
|
@ -41,7 +41,6 @@
|
||||
$element = angular.element(markup);
|
||||
$compile($element)($scope);
|
||||
$scope.$digest();
|
||||
|
||||
}));
|
||||
|
||||
it('compiles', function () {
|
||||
@ -77,7 +76,6 @@
|
||||
it('has the correct icon', function () {
|
||||
var iconSpan = $element.find('span.fa');
|
||||
expect(iconSpan.hasClass('fa-square')).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it('has the correct icon color', function () {
|
||||
@ -89,7 +87,5 @@
|
||||
expect(styleColor).toBe('#333333');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
|
@ -1,114 +0,0 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name horizon.framework.widgets.charts
|
||||
* @description
|
||||
*
|
||||
* # horizon.framework.widgets.charts
|
||||
*
|
||||
* The `horizon.framework.widgets.charts` module provides directives for simple charts
|
||||
* used in Horizon, such as the pie and donut chart. Charts are
|
||||
* implemented using D3.
|
||||
*
|
||||
* Requires {@link http://d3js.org `D3`} to be installed.
|
||||
*
|
||||
* | Constants |
|
||||
* |---------------------------------------------------------------------------|
|
||||
* | {@link horizon.framework.widgets.charts.constant:donutChartSettings `donutChartSettings`} |
|
||||
* | {@link horizon.framework.widgets.charts.constant:quotaChartDefaults `quotaChartDefaults`} |
|
||||
*
|
||||
* | Directives |
|
||||
* |---------------------------------------------------------------------------|
|
||||
* | {@link horizon.framework.widgets.charts.directive:pieChart `pieChart`} |
|
||||
*
|
||||
*/
|
||||
angular.module('horizon.framework.widgets.charts', [])
|
||||
|
||||
/**
|
||||
* @ngdoc parameters
|
||||
* @name horizon.framework.widgets.charts.constant:donutChartSettings
|
||||
* @param {number} innerRadius Pie chart inner radius in pixels, default: 24
|
||||
* @param {number} outerRadius Pie chart outer radius in pixels, default: 30
|
||||
* @param {object} label with properties font-size and fill (optional)
|
||||
* @param {string} titleClass CSS class to override title,
|
||||
* default: pie-chart-title-medium
|
||||
* alternative: pie-chart-title-large
|
||||
* @param {boolean} showTitle Show title, default: true
|
||||
* @param {boolean} showLabel Show label, default: true
|
||||
* @param {boolean} showLegend Show legend default: true
|
||||
* @param {string} tooltipIcon Tooltip key icon, default: 'fa-square'
|
||||
*
|
||||
*/
|
||||
.constant('horizon.framework.widgets.charts.donutChartSettings', {
|
||||
innerRadius: 24,
|
||||
outerRadius: 30,
|
||||
titleClass: 'pie-chart-title-medium',
|
||||
showTitle: true,
|
||||
showLabel: true,
|
||||
showLegend: true,
|
||||
tooltipIcon: 'fa-square'
|
||||
})
|
||||
|
||||
/**
|
||||
* @ngdoc parameters
|
||||
* @name horizon.framework.widgets.charts.constant:pieChartSettings
|
||||
* @param {number} innerRadius Pie chart inner radius in pixels, default: 0
|
||||
* @param {number} outerRadius Pie chart outer radius in pixels, default: 30
|
||||
* @param {object} label with properties font-size and fill (optional)
|
||||
* @param {string} titleClass CSS class to override title,
|
||||
* default: pie-chart-title-medium
|
||||
* alternative: pie-chart-title-large
|
||||
* @param {boolean} showTitle Show title, default: true
|
||||
* @param {boolean} showLabel Show label, default: true
|
||||
* @param {boolean} showLegend Show legend default: true
|
||||
* @param {string} tooltipIcon Tooltip key icon, default: 'fa-square'
|
||||
*
|
||||
*/
|
||||
.constant('horizon.framework.widgets.charts.pieChartSettings', {
|
||||
innerRadius: 0,
|
||||
outerRadius: 30,
|
||||
titleClass: 'pie-chart-title-medium',
|
||||
showTitle: true,
|
||||
showLabel: true,
|
||||
showLegend: true,
|
||||
tooltipIcon: 'fa-square'
|
||||
})
|
||||
|
||||
/**
|
||||
* @ngdoc parameters
|
||||
* @name horizon.framework.widgets.charts.constant:quotaChartDefaults
|
||||
* @param {string} usageLabel label text for Usage, default: 'Current Usage'
|
||||
* @param {string} usageColorClass css class for Usage , default: 'usage'
|
||||
* @param {string} addedLabel label text for Added, default: 'Added'
|
||||
* @param {string} addedColorClass CSS class for Added , default: 'added'
|
||||
* @param {string} remainingLabel label text for Remaining, default: 'Remaining'
|
||||
* @param {string} remainingColorClass CSS class for Remaining , default: 'remaining'
|
||||
*
|
||||
*/
|
||||
.constant('horizon.framework.widgets.charts.quotaChartDefaults', {
|
||||
usageLabel: gettext('Current Usage'),
|
||||
usageColorClass: 'usage',
|
||||
addedLabel: gettext('Added'),
|
||||
addedColorClass: 'added',
|
||||
remainingLabel: gettext('Remaining'),
|
||||
remainingColorClass: 'remaining'
|
||||
})
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name horizon.framework.widgets.charts.filter:showKeyFilter
|
||||
* @function Filter based on 'hideKey' value of each slice
|
||||
* @returns {function} A filtered list of keys to show in legend
|
||||
*
|
||||
*/
|
||||
.filter('showKeyFilter', function () {
|
||||
return function (items) {
|
||||
return items.filter(function (item) {
|
||||
return !item.hideKey;
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
})();
|
131
horizon/static/framework/widgets/charts/charts.module.js
Normal file
131
horizon/static/framework/widgets/charts/charts.module.js
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name horizon.framework.widgets.charts
|
||||
* @description
|
||||
*
|
||||
* # horizon.framework.widgets.charts
|
||||
*
|
||||
* The `horizon.framework.widgets.charts` module provides directives for simple charts
|
||||
* used in Horizon, such as the pie and donut chart. Charts are
|
||||
* implemented using D3.
|
||||
*
|
||||
* Requires {@link http://d3js.org `D3`} to be installed.
|
||||
*
|
||||
* | Constants |
|
||||
* |---------------------------------------------------------------------------|
|
||||
* | {@link horizon.framework.widgets.charts.constant:donutChartSettings `donutChartSettings`} |
|
||||
* | {@link horizon.framework.widgets.charts.constant:quotaChartDefaults `quotaChartDefaults`} |
|
||||
*
|
||||
* | Directives |
|
||||
* |---------------------------------------------------------------------------|
|
||||
* | {@link horizon.framework.widgets.charts.directive:pieChart `pieChart`} |
|
||||
*
|
||||
*/
|
||||
angular
|
||||
.module('horizon.framework.widgets.charts', [])
|
||||
|
||||
/**
|
||||
* @ngdoc parameters
|
||||
* @name horizon.framework.widgets.charts.constant:donutChartSettings
|
||||
* @param {number} innerRadius Pie chart inner radius in pixels, default: 24
|
||||
* @param {number} outerRadius Pie chart outer radius in pixels, default: 30
|
||||
* @param {object} label with properties font-size and fill (optional)
|
||||
* @param {string} titleClass CSS class to override title,
|
||||
* default: pie-chart-title-medium
|
||||
* alternative: pie-chart-title-large
|
||||
* @param {boolean} showTitle Show title, default: true
|
||||
* @param {boolean} showLabel Show label, default: true
|
||||
* @param {boolean} showLegend Show legend default: true
|
||||
* @param {string} tooltipIcon Tooltip key icon, default: 'fa-square'
|
||||
*
|
||||
*/
|
||||
.constant('horizon.framework.widgets.charts.donutChartSettings', {
|
||||
innerRadius: 24,
|
||||
outerRadius: 30,
|
||||
titleClass: 'pie-chart-title-medium',
|
||||
showTitle: true,
|
||||
showLabel: true,
|
||||
showLegend: true,
|
||||
tooltipIcon: 'fa-square'
|
||||
})
|
||||
|
||||
/**
|
||||
* @ngdoc parameters
|
||||
* @name horizon.framework.widgets.charts.constant:pieChartSettings
|
||||
* @param {number} innerRadius Pie chart inner radius in pixels, default: 0
|
||||
* @param {number} outerRadius Pie chart outer radius in pixels, default: 30
|
||||
* @param {object} label with properties font-size and fill (optional)
|
||||
* @param {string} titleClass CSS class to override title,
|
||||
* default: pie-chart-title-medium
|
||||
* alternative: pie-chart-title-large
|
||||
* @param {boolean} showTitle Show title, default: true
|
||||
* @param {boolean} showLabel Show label, default: true
|
||||
* @param {boolean} showLegend Show legend default: true
|
||||
* @param {string} tooltipIcon Tooltip key icon, default: 'fa-square'
|
||||
*
|
||||
*/
|
||||
.constant('horizon.framework.widgets.charts.pieChartSettings', {
|
||||
innerRadius: 0,
|
||||
outerRadius: 30,
|
||||
titleClass: 'pie-chart-title-medium',
|
||||
showTitle: true,
|
||||
showLabel: true,
|
||||
showLegend: true,
|
||||
tooltipIcon: 'fa-square'
|
||||
})
|
||||
|
||||
/**
|
||||
* @ngdoc parameters
|
||||
* @name horizon.framework.widgets.charts.constant:quotaChartDefaults
|
||||
* @param {string} usageLabel label text for Usage, default: 'Current Usage'
|
||||
* @param {string} usageColorClass css class for Usage , default: 'usage'
|
||||
* @param {string} addedLabel label text for Added, default: 'Added'
|
||||
* @param {string} addedColorClass CSS class for Added , default: 'added'
|
||||
* @param {string} remainingLabel label text for Remaining, default: 'Remaining'
|
||||
* @param {string} remainingColorClass CSS class for Remaining , default: 'remaining'
|
||||
*
|
||||
*/
|
||||
.constant('horizon.framework.widgets.charts.quotaChartDefaults', {
|
||||
usageLabel: gettext('Current Usage'),
|
||||
usageColorClass: 'usage',
|
||||
addedLabel: gettext('Added'),
|
||||
addedColorClass: 'added',
|
||||
remainingLabel: gettext('Remaining'),
|
||||
remainingColorClass: 'remaining'
|
||||
})
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name horizon.framework.widgets.charts.filter:showKeyFilter
|
||||
* @function Filter based on 'hideKey' value of each slice
|
||||
* @returns {function} A filtered list of keys to show in legend
|
||||
*
|
||||
*/
|
||||
.filter('showKeyFilter', showKeyFilter);
|
||||
|
||||
function showKeyFilter() {
|
||||
return function (items) {
|
||||
return items.filter(function (item) {
|
||||
return !item.hideKey;
|
||||
});
|
||||
};
|
||||
}
|
||||
})();
|
232
horizon/static/framework/widgets/charts/pie-chart.directive.js
Normal file
232
horizon/static/framework/widgets/charts/pie-chart.directive.js
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name horizon.framework.widgets.charts.directive:pieChart
|
||||
* @element
|
||||
* @param {object} chart-data The chart data model
|
||||
* @param {string} chart-settings The custom chart settings (JSON), optional
|
||||
* @description
|
||||
* The `pieChart` directive renders a pie or donut chart using D3. The title
|
||||
* and legend is shown by default. Each slice is represented by a label, value,
|
||||
* and color (hex value or CSS class). See below for the data model.
|
||||
*
|
||||
* Data Model:
|
||||
* ```
|
||||
* var chartData = {
|
||||
* title: 'Total Instances',
|
||||
* label: '25%',
|
||||
* maxLimit: 10,
|
||||
* overMax: false,
|
||||
* data: [
|
||||
* { label: quotaChartDefaults.usageLabel, value: 1, colorClass: quotaChartDefaults.usageColorClass},
|
||||
* { label: quotaChartDefaults.addedLabel, value: 1, colorClass: quotaChartDefaults.addedColorClass },
|
||||
* { label: quotaChartDefaults.remainingLabel, value: 1, colorClass: quotaChartDefaults.remainingColorClass }
|
||||
* ]
|
||||
* };
|
||||
*
|
||||
* title - the chart title
|
||||
* label - the text to show in center of chart
|
||||
* maxLimit - the max limit for current item (optional)
|
||||
* - if a maxLimit is specified, (# Max) will get added to the chart title
|
||||
* - otherwise (# Total) will be added to the chart title
|
||||
* overMax - used to notify view when max is surpassed so that we can
|
||||
* dynamically alter UI to warn the user (optional)
|
||||
* data - the data used to render chart
|
||||
*
|
||||
* Donut chart settings (donutChartSettings) and pie chart settings (pieChartSettings)
|
||||
* are conveniently defined as angular constants in order to encourage consistency.
|
||||
* To leverage the constant values, you will need to specify them as dependencies
|
||||
* in your controller or directive. You can also create a custom styled chart
|
||||
* by defining a chartSettings object in your controller and passing it in as
|
||||
* the chart-settings attribute value.
|
||||
*
|
||||
* var chartSettings = {
|
||||
* innerRadius: 24,
|
||||
* outerRadius: 30,
|
||||
* titleClass: 'pie-chart-title-medium',
|
||||
* showTitle: true,
|
||||
* showLabel: true,
|
||||
* showLegend: true,
|
||||
* tooltipIcon: 'fa-square'
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @restrict E
|
||||
* @scope true
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* Pie Chart using predefined constant:
|
||||
* <pie-chart chart-data='chartData'
|
||||
* chart-settings='pieChartSettings'></pie-chart>
|
||||
*
|
||||
* Donut Chart using predefined constant:
|
||||
* <pie-chart chart-data='chartData'
|
||||
* chart-settings='donutChartSettings'></pie-chart>
|
||||
*
|
||||
* Custom Chart using custom settings:
|
||||
* <pie-chart chart-data='chartData'
|
||||
* chart-settings='chartSettings'></pie-chart>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
angular
|
||||
.module('horizon.framework.widgets.charts')
|
||||
.directive('pieChart', pieChart);
|
||||
|
||||
pieChart.$inject = [
|
||||
'horizon.framework.widgets.basePath',
|
||||
'horizon.framework.widgets.charts.donutChartSettings'
|
||||
];
|
||||
|
||||
function pieChart(path, donutChartSettings) {
|
||||
var directive = {
|
||||
link: link,
|
||||
replace: true,
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
chartData: '=',
|
||||
chartSettings: '='
|
||||
},
|
||||
templateUrl: path + 'charts/pie-chart.html'
|
||||
};
|
||||
|
||||
return directive;
|
||||
|
||||
function link(scope, element) {
|
||||
var settings = {};
|
||||
// if chartSettings is defined via the attribute value, use it
|
||||
if (angular.isObject(scope.chartSettings)) {
|
||||
settings = scope.chartSettings;
|
||||
} else {
|
||||
// else default to a donut chart
|
||||
settings = angular.extend({}, donutChartSettings, scope.chartSettings);
|
||||
}
|
||||
settings.diameter = settings.outerRadius * 2;
|
||||
|
||||
var model = {
|
||||
settings: settings,
|
||||
tooltipData: {
|
||||
enabled: false,
|
||||
icon: settings.tooltipIcon,
|
||||
style: angular.extend({}, settings.tooltip)
|
||||
}
|
||||
};
|
||||
|
||||
var d3Elt = d3.select(element[0]);
|
||||
|
||||
var arc = d3.svg.arc()
|
||||
.outerRadius(settings.outerRadius)
|
||||
.innerRadius(settings.innerRadius);
|
||||
|
||||
var pie = d3.layout.pie()
|
||||
.sort(null)
|
||||
.value(function (d) { return d.value; });
|
||||
|
||||
var unwatch = scope.$watch('chartData', updateChart);
|
||||
scope.$on('$destroy', unwatch);
|
||||
|
||||
scope.model = model;
|
||||
|
||||
function updateChart() {
|
||||
// set labels depending on whether this is a max or total chart
|
||||
if (angular.isDefined(scope.chartData.maxLimit)) {
|
||||
scope.model.total = scope.chartData.maxLimit;
|
||||
scope.model.totalLabel = gettext('Max');
|
||||
} else {
|
||||
scope.model.total = d3.sum(scope.chartData.data, function (d) { return d.value; });
|
||||
scope.model.totalLabel = gettext('Total');
|
||||
}
|
||||
scope.model.tooltipData.enabled = false;
|
||||
|
||||
// Generate or update slices
|
||||
var chart = d3Elt.select('.slices')
|
||||
.selectAll('path.slice')
|
||||
.data(pie(scope.chartData.data));
|
||||
|
||||
chart.enter().append('path')
|
||||
.attr('class', 'slice')
|
||||
.attr('d', arc);
|
||||
|
||||
// Set the color or CSS class for the fill
|
||||
chart.each(function (d) {
|
||||
var slice = d3.select(this);
|
||||
if (d.data.color) {
|
||||
slice.style('fill', d.data.color);
|
||||
} else if (d.data.colorClass) {
|
||||
slice.classed(d.data.colorClass, true);
|
||||
}
|
||||
});
|
||||
|
||||
chart.on('mouseenter', function (d) { showTooltip(d, this); })
|
||||
.on('mouseleave', clearTooltip);
|
||||
|
||||
// Animate the slice rendering
|
||||
chart.transition()
|
||||
.duration(500)
|
||||
.attrTween('d', function animate(d) {
|
||||
this.lastAngle = this.lastAngle || { startAngle: 0, endAngle: 0 };
|
||||
var interpolate = d3.interpolate(this.lastAngle, d);
|
||||
this.lastAngle = interpolate(0);
|
||||
|
||||
return function (t) {
|
||||
return arc(interpolate(t));
|
||||
};
|
||||
});
|
||||
|
||||
chart.exit().remove();
|
||||
}
|
||||
|
||||
function showTooltip(d, elt) {
|
||||
scope.$apply(function () {
|
||||
var chartElt = element[0];
|
||||
var eltHeight = chartElt.getBoundingClientRect().height;
|
||||
var titleHeight = chartElt.querySelector('div.pie-chart-title')
|
||||
.getBoundingClientRect()
|
||||
.height;
|
||||
|
||||
var point = d3.mouse(elt);
|
||||
var outerRadius = scope.model.settings.outerRadius;
|
||||
var x = point[0] + outerRadius;
|
||||
var y = eltHeight - point[1] - outerRadius - titleHeight;
|
||||
|
||||
var newTooltipData = {
|
||||
label: d.data.label,
|
||||
value: d.data.value,
|
||||
enabled: true,
|
||||
iconColor: d.data.color,
|
||||
iconClass: d.data.colorClass,
|
||||
style: {
|
||||
left: x + 'px',
|
||||
bottom: y + 'px'
|
||||
}
|
||||
};
|
||||
angular.extend(scope.model.tooltipData, newTooltipData);
|
||||
});
|
||||
}
|
||||
|
||||
function clearTooltip() {
|
||||
scope.$apply(function () {
|
||||
scope.model.tooltipData.enabled = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
@ -1,206 +0,0 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular.module('horizon.framework.widgets.charts')
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name horizon.framework.widgets.charts.directive:pieChart
|
||||
* @element
|
||||
* @param {object} chart-data The chart data model
|
||||
* @param {string} chart-settings The custom chart settings (JSON), optional
|
||||
* @description
|
||||
* The `pieChart` directive renders a pie or donut chart using D3. The title
|
||||
* and legend is shown by default. Each slice is represented by a label, value,
|
||||
* and color (hex value or CSS class). See below for the data model.
|
||||
*
|
||||
* Data Model:
|
||||
* ```
|
||||
* var chartData = {
|
||||
* title: 'Total Instances',
|
||||
* label: '25%',
|
||||
* maxLimit: 10,
|
||||
* overMax: false,
|
||||
* data: [
|
||||
* { label: quotaChartDefaults.usageLabel, value: 1, colorClass: quotaChartDefaults.usageColorClass},
|
||||
* { label: quotaChartDefaults.addedLabel, value: 1, colorClass: quotaChartDefaults.addedColorClass },
|
||||
* { label: quotaChartDefaults.remainingLabel, value: 1, colorClass: quotaChartDefaults.remainingColorClass }
|
||||
* ]
|
||||
* };
|
||||
*
|
||||
* title - the chart title
|
||||
* label - the text to show in center of chart
|
||||
* maxLimit - the max limit for current item (optional)
|
||||
* - if a maxLimit is specified, (# Max) will get added to the chart title
|
||||
* - otherwise (# Total) will be added to the chart title
|
||||
* overMax - used to notify view when max is surpassed so that we can
|
||||
* dynamically alter UI to warn the user (optional)
|
||||
* data - the data used to render chart
|
||||
*
|
||||
* Donut chart settings (donutChartSettings) and pie chart settings (pieChartSettings)
|
||||
* are conveniently defined as angular constants in order to encourage consistency.
|
||||
* To leverage the constant values, you will need to specify them as dependencies
|
||||
* in your controller or directive. You can also create a custom styled chart
|
||||
* by defining a chartSettings object in your controller and passing it in as
|
||||
* the chart-settings attribute value.
|
||||
*
|
||||
* var chartSettings = {
|
||||
* innerRadius: 24,
|
||||
* outerRadius: 30,
|
||||
* titleClass: 'pie-chart-title-medium',
|
||||
* showTitle: true,
|
||||
* showLabel: true,
|
||||
* showLegend: true,
|
||||
* tooltipIcon: 'fa-square'
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @restrict E
|
||||
* @scope true
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* Pie Chart using predefined constant:
|
||||
* <pie-chart chart-data='chartData'
|
||||
* chart-settings='pieChartSettings'></pie-chart>
|
||||
*
|
||||
* Donut Chart using predefined constant:
|
||||
* <pie-chart chart-data='chartData'
|
||||
* chart-settings='donutChartSettings'></pie-chart>
|
||||
*
|
||||
* Custom Chart using custom settings:
|
||||
* <pie-chart chart-data='chartData'
|
||||
* chart-settings='chartSettings'></pie-chart>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
.directive('pieChart', [
|
||||
'horizon.framework.widgets.basePath',
|
||||
'horizon.framework.widgets.charts.donutChartSettings',
|
||||
function (path, donutChartSettings) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
chartData: '=',
|
||||
chartSettings: '='
|
||||
},
|
||||
replace: true,
|
||||
templateUrl: path + 'charts/pie-chart.html',
|
||||
link: function (scope, element) {
|
||||
var settings = {};
|
||||
// if chartSettings is defined via the attribute value, use it
|
||||
if (angular.isObject(scope.chartSettings)) {
|
||||
settings = scope.chartSettings;
|
||||
} else {
|
||||
// else default to a donut chart
|
||||
settings = angular.extend({}, donutChartSettings, scope.chartSettings);
|
||||
}
|
||||
settings.diameter = settings.outerRadius * 2;
|
||||
|
||||
var model = {
|
||||
settings: settings,
|
||||
tooltipData: {
|
||||
enabled: false,
|
||||
icon: settings.tooltipIcon,
|
||||
style: angular.extend({}, settings.tooltip)
|
||||
}
|
||||
};
|
||||
|
||||
var d3Elt = d3.select(element[0]);
|
||||
|
||||
var arc = d3.svg.arc()
|
||||
.outerRadius(settings.outerRadius)
|
||||
.innerRadius(settings.innerRadius);
|
||||
|
||||
var pie = d3.layout.pie()
|
||||
.sort(null)
|
||||
.value(function (d) { return d.value; });
|
||||
|
||||
var unwatch = scope.$watch('chartData', updateChart);
|
||||
scope.$on('$destroy', unwatch);
|
||||
|
||||
scope.model = model;
|
||||
|
||||
function updateChart() {
|
||||
// set labels depending on whether this is a max or total chart
|
||||
if (angular.isDefined(scope.chartData.maxLimit)) {
|
||||
scope.model.total = scope.chartData.maxLimit;
|
||||
scope.model.totalLabel = gettext('Max');
|
||||
} else {
|
||||
scope.model.total = d3.sum(scope.chartData.data, function (d) { return d.value; });
|
||||
scope.model.totalLabel = gettext('Total');
|
||||
}
|
||||
scope.model.tooltipData.enabled = false;
|
||||
|
||||
// Generate or update slices
|
||||
var chart = d3Elt.select('.slices')
|
||||
.selectAll('path.slice')
|
||||
.data(pie(scope.chartData.data));
|
||||
|
||||
chart.enter().append('path')
|
||||
.attr('class', 'slice')
|
||||
.attr('d', arc);
|
||||
|
||||
// Set the color or CSS class for the fill
|
||||
chart.each(function (d) {
|
||||
var slice = d3.select(this);
|
||||
if (d.data.color) {
|
||||
slice.style('fill', d.data.color);
|
||||
} else if (d.data.colorClass) {
|
||||
slice.classed(d.data.colorClass, true);
|
||||
}
|
||||
});
|
||||
|
||||
chart.on('mouseenter', function (d) { showTooltip(d, this); })
|
||||
.on('mouseleave', clearTooltip);
|
||||
|
||||
// Animate the slice rendering
|
||||
chart.transition()
|
||||
.duration(500)
|
||||
.attrTween('d', function animate(d) {
|
||||
this.lastAngle = this.lastAngle || { startAngle: 0, endAngle: 0 };
|
||||
var interpolate = d3.interpolate(this.lastAngle, d);
|
||||
this.lastAngle = interpolate(0);
|
||||
|
||||
return function (t) {
|
||||
return arc(interpolate(t));
|
||||
};
|
||||
});
|
||||
|
||||
chart.exit().remove();
|
||||
}
|
||||
|
||||
function showTooltip(d, elt) {
|
||||
scope.$apply(function () {
|
||||
var chartElt = element[0];
|
||||
var eltHeight = chartElt.getBoundingClientRect().height;
|
||||
var titleHeight = chartElt.querySelector('div.pie-chart-title')
|
||||
.getBoundingClientRect()
|
||||
.height;
|
||||
|
||||
var point = d3.mouse(elt);
|
||||
var outerRadius = scope.model.settings.outerRadius;
|
||||
var x = point[0] + outerRadius;
|
||||
var y = eltHeight - point[1] - outerRadius - titleHeight;
|
||||
|
||||
scope.model.tooltipData.label = d.data.label;
|
||||
scope.model.tooltipData.value = d.data.value;
|
||||
scope.model.tooltipData.enabled = true;
|
||||
scope.model.tooltipData.iconColor = d.data.color;
|
||||
scope.model.tooltipData.iconClass = d.data.colorClass;
|
||||
scope.model.tooltipData.style.left = x + 'px';
|
||||
scope.model.tooltipData.style.bottom = y + 'px';
|
||||
});
|
||||
}
|
||||
|
||||
function clearTooltip() {
|
||||
scope.$apply(function () {
|
||||
scope.model.tooltipData.enabled = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
@ -1,3 +1,18 @@
|
||||
/*
|
||||
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function () {
|
||||
|
||||
'use strict';
|
||||
|
@ -52,9 +52,9 @@ class ServicesTests(test.JasmineTests):
|
||||
'framework/widgets/widgets.module.js',
|
||||
'framework/widgets/action-list/action-list.js',
|
||||
'framework/widgets/action-list/button-tooltip.js',
|
||||
'framework/widgets/charts/charts.js',
|
||||
'framework/widgets/charts/chart-tooltip.js',
|
||||
'framework/widgets/charts/pie-chart.js',
|
||||
'framework/widgets/charts/charts.module.js',
|
||||
'framework/widgets/charts/chart-tooltip.directive.js',
|
||||
'framework/widgets/charts/pie-chart.directive.js',
|
||||
'framework/widgets/help-panel/help-panel.js',
|
||||
'framework/widgets/magic-search/magic-search.js',
|
||||
'framework/widgets/metadata-tree/metadata-tree.js',
|
||||
|
@ -60,9 +60,9 @@
|
||||
<script src='{{ STATIC_URL }}framework/widgets/modal/modal.factory.js'></script>
|
||||
<script src='{{ STATIC_URL }}framework/widgets/modal-wait-spinner/modal-wait-spinner.js'></script>
|
||||
<script src='{{ STATIC_URL }}framework/widgets/transfer-table/transfer-table.js'></script>
|
||||
<script src='{{ STATIC_URL }}framework/widgets/charts/charts.js'></script>
|
||||
<script src='{{ STATIC_URL }}framework/widgets/charts/chart-tooltip.js'></script>
|
||||
<script src='{{ STATIC_URL }}framework/widgets/charts/pie-chart.js'></script>
|
||||
<script src='{{ STATIC_URL }}framework/widgets/charts/charts.module.js'></script>
|
||||
<script src='{{ STATIC_URL }}framework/widgets/charts/chart-tooltip.directive.js'></script>
|
||||
<script src='{{ STATIC_URL }}framework/widgets/charts/pie-chart.directive.js'></script>
|
||||
<script src='{{ STATIC_URL }}framework/widgets/metadata-tree/metadata-tree.js'></script>
|
||||
<script src='{{ STATIC_URL }}framework/widgets/metadata-tree/metadata-tree-service.js'></script>
|
||||
<script src='{{ STATIC_URL }}framework/widgets/metadata-display/metadata-display.js'></script>
|
||||
|
Loading…
Reference in New Issue
Block a user