diff --git a/horizon/karma.conf.js b/horizon/karma.conf.js index 9972fe5a89..c32fb35759 100644 --- a/horizon/karma.conf.js +++ b/horizon/karma.conf.js @@ -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', diff --git a/horizon/static/framework/widgets/charts/chart-tooltip.directive.js b/horizon/static/framework/widgets/charts/chart-tooltip.directive.js new file mode 100644 index 0000000000..c800e5bdcf --- /dev/null +++ b/horizon/static/framework/widgets/charts/chart-tooltip.directive.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 + * ``` + * + * ``` + * + */ + 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; + } +})(); diff --git a/horizon/static/framework/widgets/charts/chart-tooltip.js b/horizon/static/framework/widgets/charts/chart-tooltip.js deleted file mode 100644 index d314ab1fa5..0000000000 --- a/horizon/static/framework/widgets/charts/chart-tooltip.js +++ /dev/null @@ -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 - * ``` - * - * ``` - * - */ - .directive('chartTooltip', [ 'horizon.framework.widgets.basePath', function (path) { - return { - restrict: 'E', - scope: { - tooltip: '=tooltipData' - }, - templateUrl: path + 'charts/chart-tooltip.html' - }; - }]); - -})(); diff --git a/horizon/static/framework/widgets/charts/chart-tooltip.spec.js b/horizon/static/framework/widgets/charts/chart-tooltip.spec.js index 081d5352c3..4f26e724f4 100644 --- a/horizon/static/framework/widgets/charts/chart-tooltip.spec.js +++ b/horizon/static/framework/widgets/charts/chart-tooltip.spec.js @@ -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'); } }); - }); - })(); diff --git a/horizon/static/framework/widgets/charts/charts.js b/horizon/static/framework/widgets/charts/charts.js deleted file mode 100644 index 0c1a049dae..0000000000 --- a/horizon/static/framework/widgets/charts/charts.js +++ /dev/null @@ -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; - }); - }; - }); - -})(); diff --git a/horizon/static/framework/widgets/charts/charts.module.js b/horizon/static/framework/widgets/charts/charts.module.js new file mode 100644 index 0000000000..3a102ecfdd --- /dev/null +++ b/horizon/static/framework/widgets/charts/charts.module.js @@ -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; + }); + }; + } +})(); diff --git a/horizon/static/framework/widgets/charts/pie-chart.directive.js b/horizon/static/framework/widgets/charts/pie-chart.directive.js new file mode 100644 index 0000000000..7bf838e04d --- /dev/null +++ b/horizon/static/framework/widgets/charts/pie-chart.directive.js @@ -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: + * + * + * Donut Chart using predefined constant: + * + * + * Custom Chart using custom settings: + * + * ``` + * + */ + 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; + }); + } + } + } +})(); diff --git a/horizon/static/framework/widgets/charts/pie-chart.js b/horizon/static/framework/widgets/charts/pie-chart.js deleted file mode 100644 index 42a7760dfe..0000000000 --- a/horizon/static/framework/widgets/charts/pie-chart.js +++ /dev/null @@ -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: - * - * - * Donut Chart using predefined constant: - * - * - * Custom Chart using custom settings: - * - * ``` - * - */ - .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; - }); - } - } - }; - } - ]); - -})(); diff --git a/horizon/static/framework/widgets/charts/pie-chart.spec.js b/horizon/static/framework/widgets/charts/pie-chart.spec.js index ce685d3ade..eb28f921ca 100644 --- a/horizon/static/framework/widgets/charts/pie-chart.spec.js +++ b/horizon/static/framework/widgets/charts/pie-chart.spec.js @@ -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'; diff --git a/horizon/test/jasmine/jasmine_tests.py b/horizon/test/jasmine/jasmine_tests.py index 176d4a7995..cc8725be15 100644 --- a/horizon/test/jasmine/jasmine_tests.py +++ b/horizon/test/jasmine/jasmine_tests.py @@ -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', diff --git a/openstack_dashboard/templates/horizon/_scripts.html b/openstack_dashboard/templates/horizon/_scripts.html index fe63942731..bc32b5d2ce 100644 --- a/openstack_dashboard/templates/horizon/_scripts.html +++ b/openstack_dashboard/templates/horizon/_scripts.html @@ -60,9 +60,9 @@ - - - + + +