UNPKG

angularjs-nvd3-directives

Version:
1,006 lines (929 loc) 119 kB
/* Common functions that sets up width, height, margin should prevent NaN errors */ function initializeMargin(scope, attrs){ var margin = (scope.$eval(attrs.margin) || {left: 50, top: 50, bottom: 50, right: 50}); if (typeof(margin) !== 'object') { // we were passed a vanilla int, convert to full margin object margin = {left: margin, top: margin, bottom: margin, right: margin}; } scope.margin = margin; } function getD3Selector(attrs, element) { if (!attrs.id) { //if an id is not supplied, create a random id. var dataAttributeChartID; if (!attrs['data-chartid']) { dataAttributeChartID = 'chartid' + Math.floor(Math.random() * 1000000001); angular.element(element).attr('data-chartid', dataAttributeChartID); } else { dataAttributeChartID = attrs['data-chartid']; } return '[data-chartid=' + dataAttributeChartID + ']'; } else { return '#' + attrs.id; } } function checkElementID(scope, attrs, element, chart, data) { configureXaxis(chart, scope, attrs); configureX2axis(chart, scope, attrs); configureYaxis(chart, scope, attrs); configureY1axis(chart, scope, attrs); configureY2axis(chart, scope, attrs); configureLegend(chart, scope, attrs); processEvents(chart, scope); var d3Select = getD3Selector(attrs, element); if (angular.isArray(data) && data.length === 0) { d3.select(d3Select + ' svg').remove(); } if (d3.select(d3Select + ' svg').empty()) { d3.select(d3Select) .append('svg'); } d3.select(d3Select + ' svg') .attr('viewBox', '0 0 ' + scope.width + ' ' + scope.height) .datum(data) .transition().duration((attrs.transitionduration === undefined ? 250 : (+attrs.transitionduration))) .call(chart); } function updateDimensions(scope, attrs, element, chart) { if (chart) { chart.width(scope.width).height(scope.height); var d3Select = getD3Selector(attrs, element); d3.select(d3Select + ' svg') .attr('viewBox', '0 0 ' + scope.width + ' ' + scope.height); nv.utils.windowResize(chart); scope.chart.update(); } } angular.module('nvd3ChartDirectives', []) .directive('nvd3LineChart', ['$filter', function($filter){ return { restrict: 'EA', scope: { data: '=', filtername: '=', filtervalue: '=', width: '@', height: '@', id: '@', showlegend: '@', tooltips: '@', showxaxis: '@', showyaxis: '@', rightalignyaxis: '@', defaultstate: '@', nodata: '@', margin: '&', tooltipcontent: '&', color: '&', x: '&', y: '&', forcex: '@', forcey: '@', isArea: '@', interactive: '@', clipedge: '@', clipvoronoi: '@', interpolate: '@', callback: '&', useinteractiveguideline: '@', //xaxis xaxisorient: '&', xaxisticks: '@', xaxistickvalues: '&xaxistickvalues', xaxisticksubdivide: '&', xaxisticksize: '&', xaxistickpadding: '&', xaxistickformat: '&', xaxislabel: '@', xaxisscale: '&', xaxisdomain: '&', xaxisrange: '&', xaxisrangeband: '&', xaxisrangebands: '&', xaxisshowmaxmin: '@', xaxishighlightzero: '@', xaxisrotatelabels: '@', xaxisrotateylabel: '@', xaxisstaggerlabels: '@', xaxislabeldistance: '@', //yaxis yaxisorient: '&', yaxisticks: '&', yaxistickvalues: '&yaxistickvalues', yaxisticksubdivide: '&', yaxisticksize: '&', yaxistickpadding: '&', yaxistickformat: '&', yaxislabel: '@', yaxisscale: '&', yaxisdomain: '&', yaxisrange: '&', yaxisrangeband: '&', yaxisrangebands: '&', yaxisshowmaxmin: '@', yaxishighlightzero: '@', yaxisrotatelabels: '@', yaxisrotateylabel: '@', yaxisstaggerlabels: '@', yaxislabeldistance: '@', legendmargin: '&', legendwidth: '@', legendheight: '@', legendkey: '@', legendcolor: '&', legendalign: '@', legendrightalign: '@', legendupdatestate: '@', legendradiobuttonmode: '@', //angularjs specific objectequality: '@', //$watch(watchExpression, listener, objectEquality) //d3.js specific transitionduration: '@' }, controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs){ $scope.d3Call = function(data, chart){ checkElementID($scope, $attrs, $element, chart, data); }; }], link: function(scope, element, attrs){ scope.$watch('width + height', function() { updateDimensions(scope,attrs,element,scope.chart); }); scope.$watch('data', function(data){ if (data && angular.isDefined(scope.filtername) && angular.isDefined(scope.filtervalue)) { data = $filter(scope.filtername)(data, scope.filtervalue); } if(data){ //if the chart exists on the scope, do not call addGraph again, update data and call the chart. if(scope.chart){ return scope.d3Call(data, scope.chart); } nv.addGraph({ generate: function(){ initializeMargin(scope, attrs); var chart = nv.models.lineChart() .width(scope.width) .height(scope.height) .margin(scope.margin) .x(attrs.x === undefined ? function(d){ return d[0]; } : scope.x()) .y(attrs.y === undefined ? function(d){ return d[1]; } : scope.y()) .forceX(attrs.forcex === undefined ? [] : scope.$eval(attrs.forcex)) // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.) .forceY(attrs.forcey === undefined ? [0] : scope.$eval(attrs.forcey)) // List of numbers to Force into the Y scale .showLegend(attrs.showlegend === undefined ? false : (attrs.showlegend === 'true')) .tooltips(attrs.tooltips === undefined ? false : (attrs.tooltips === 'true')) .showXAxis(attrs.showxaxis === undefined ? false : (attrs.showxaxis === 'true')) .showYAxis(attrs.showyaxis === undefined ? false : (attrs.showyaxis === 'true')) .rightAlignYAxis(attrs.rightalignyaxis === undefined ? false : (attrs.rightalignyaxis === 'true')) .noData(attrs.nodata === undefined ? 'No Data Available.' : scope.nodata) .interactive(attrs.interactive === undefined ? false : (attrs.interactive === 'true')) .clipEdge(attrs.clipedge === undefined ? false : (attrs.clipedge === 'true')) .clipVoronoi(attrs.clipvoronoi === undefined ? false : (attrs.clipvoronoi === 'true')) .interpolate(attrs.interpolate === undefined ? 'linear' : attrs.interpolate) .color(attrs.color === undefined ? nv.utils.defaultColor() : scope.color()) .isArea(attrs.isarea === undefined ? function(d) { return d.area; } : function(){ return (attrs.isarea === 'true'); }); if (attrs.useinteractiveguideline) { chart.useInteractiveGuideline(attrs.useinteractiveguideline === undefined ? false : (attrs.useinteractiveguideline === 'true')); } if(attrs.tooltipcontent){ chart.tooltipContent(scope.tooltipcontent()); } scope.d3Call(data, chart); nv.utils.windowResize(chart.update); scope.chart = chart; return chart; }, callback: attrs.callback === undefined ? null : scope.callback() }); } }, (attrs.objectequality === undefined ? false : (attrs.objectequality === 'true'))); } }; }]) .directive('nvd3CumulativeLineChart', ['$filter', function($filter){ return { restrict: 'EA', scope: { data: '=', filtername: '=', filtervalue: '=', width: '@', height: '@', id: '@', showlegend: '@', tooltips: '@', showxaxis: '@', showyaxis: '@', rightalignyaxis: '@', defaultstate: '@', nodata: '@', margin: '&', tooltipcontent: '&', color: '&', x: '&', y: '&', forcex: '@', forcey: '@', isArea: '@', interactive: '@', clipedge: '@', clipvoronoi: '@', usevoronoi: '@', average: '&', rescaley: '@', callback: '&', useinteractiveguideline: '@', //xaxis xaxisorient: '&', xaxisticks: '&', xaxistickvalues: '&xaxistickvalues', xaxisticksubdivide: '&', xaxisticksize: '&', xaxistickpadding: '&', xaxistickformat: '&', xaxislabel: '@', xaxisscale: '&', xaxisdomain: '&', xaxisrange: '&', xaxisrangeband: '&', xaxisrangebands: '&', xaxisshowmaxmin: '@', xaxishighlightzero: '@', xaxisrotatelabels: '@', xaxisrotateylabel: '@', xaxisstaggerlabels: '@', xaxislabeldistance: '@', //yaxis yaxisorient: '&', yaxisticks: '&', yaxistickvalues: '&yaxistickvalues', yaxisticksubdivide: '&', yaxisticksize: '&', yaxistickpadding: '&', yaxistickformat: '&', yaxislabel: '@', yaxisscale: '&', yaxisdomain: '&', yaxisrange: '&', yaxisrangeband: '&', yaxisrangebands: '&', yaxisshowmaxmin: '@', yaxishighlightzero: '@', yaxisrotatelabels: '@', yaxisrotateylabel: '@', yaxisstaggerlabels: '@', yaxislabeldistance: '@', legendmargin: '&', legendwidth: '@', legendheight: '@', legendkey: '@', legendcolor: '&', legendalign: '@', legendrightalign: '@', legendupdatestate: '@', legendradiobuttonmode: '@', //angularjs specific objectequality: '@', //$watch(watchExpression, listener, objectEquality) //d3.js specific transitionduration: '@' }, controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs){ $scope.d3Call = function(data, chart){ checkElementID($scope, $attrs, $element, chart, data); }; }], link: function(scope, element, attrs){ scope.$watch('width + height', function() { updateDimensions(scope,attrs,element,scope.chart); }); scope.$watch('data', function(data){ if (data && angular.isDefined(scope.filtername) && angular.isDefined(scope.filtervalue)) { data = $filter(scope.filtername)(data, scope.filtervalue); } if(data){ //if the chart exists on the scope, do not call addGraph again, update data and call the chart. if(scope.chart){ return scope.d3Call(data, scope.chart); } nv.addGraph({ generate: function(){ initializeMargin(scope, attrs); var chart = nv.models.cumulativeLineChart() .width(scope.width) .height(scope.height) .margin(scope.margin) .x(attrs.x === undefined ? function(d){ return d[0]; } : scope.x()) .y(attrs.y === undefined ? function(d){ return d[1]; } : scope.y()) .forceX(attrs.forcex === undefined ? [] : scope.$eval(attrs.forcex)) // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.) .forceY(attrs.forcey === undefined ? [0] : scope.$eval(attrs.forcey)) // List of numbers to Force into the Y scale .showLegend(attrs.showlegend === undefined ? false : (attrs.showlegend === 'true')) .tooltips(attrs.tooltips === undefined ? false : (attrs.tooltips === 'true')) .showXAxis(attrs.showxaxis === undefined ? false : (attrs.showxaxis === 'true')) .showYAxis(attrs.showyaxis === undefined ? false : (attrs.showyaxis === 'true')) .rightAlignYAxis(attrs.rightalignyaxis === undefined ? false : (attrs.rightalignyaxis === 'true')) .noData(attrs.nodata === undefined ? 'No Data Available.' : scope.nodata) .interactive(attrs.interactive === undefined ? false : (attrs.interactive === 'true')) .clipEdge(attrs.clipedge === undefined ? false : (attrs.clipedge === 'true')) .clipVoronoi(attrs.clipvoronoi === undefined ? false : (attrs.clipvoronoi === 'true')) .useVoronoi(attrs.usevoronoi === undefined ? false : (attrs.usevoronoi === 'true')) .average(attrs.average === undefined ? function(d) { return d.average; } : scope.average()) .color(attrs.color === undefined ? d3.scale.category10().range() : scope.color()) .isArea(attrs.isarea === undefined ? function(d) { return d.area; } : (attrs.isarea === 'true')); //.rescaleY(attrs.rescaley === undefined ? false : (attrs.rescaley === 'true')); if (attrs.useinteractiveguideline) { chart.useInteractiveGuideline(attrs.useinteractiveguideline === undefined ? false : (attrs.useinteractiveguideline === 'true')); } if(attrs.tooltipcontent){ chart.tooltipContent(scope.tooltipcontent()); } scope.d3Call(data, chart); nv.utils.windowResize(chart.update); scope.chart = chart; return chart; }, callback: attrs.callback === undefined ? null : scope.callback() }); } }, (attrs.objectequality === undefined ? false : (attrs.objectequality === 'true'))); } }; }]) .directive('nvd3StackedAreaChart', ['$filter', function($filter){ return { restrict: 'EA', scope: { data: '=', filtername: '=', filtervalue: '=', width: '@', height: '@', id: '@', showlegend: '@', tooltips: '@', showcontrols: '@', nodata: '@', margin: '&', tooltipcontent: '&', color: '&', x: '&', y: '&', forcex: '@', //List of numbers to Force into the X scale (ie. 0, or a max / min, etc.) forcey: '@', // List of numbers to Force into the Y scale forcesize: '@', // List of numbers to Force into the Size scale interactive: '@', usevoronoi: '@', clipedge: '@', interpolate: '@', style: '@', //stack, stream, stream-center, expand order: '@', //default, inside-out offset: '@', //zero, wiggle, silhouette, expand size: '&', //accessor to get the point size xScale: '&', yScale: '&', xDomain: '&', yDomain: '&', xRange: '&', yRange: '&', sizeDomain: '&', callback: '&', //xaxis showxaxis: '&', xaxisorient: '&', xaxisticks: '&', xaxistickvalues: '&xaxistickvalues', xaxisticksubdivide: '&', xaxisticksize: '&', xaxistickpadding: '&', xaxistickformat: '&', xaxislabel: '@', xaxisscale: '&', xaxisdomain: '&', xaxisrange: '&', xaxisrangeband: '&', xaxisrangebands: '&', xaxisshowmaxmin: '@', xaxishighlightzero: '@', xaxisrotatelabels: '@', xaxisrotateylabel: '@', xaxisstaggerlabels: '@', xaxisaxislabeldistance: '@', //yaxis showyaxis: '&', useinteractiveguideline: '@', yaxisorient: '&', yaxisticks: '&', yaxistickvalues: '&yaxistickvalues', yaxisticksubdivide: '&', yaxisticksize: '&', yaxistickpadding: '&', yaxistickformat: '&', yaxislabel: '@', yaxisscale: '&', yaxisdomain: '&', yaxisrange: '&', yaxisrangeband: '&', yaxisrangebands: '&', yaxisshowmaxmin: '@', yaxishighlightzero: '@', yaxisrotatelabels: '@', yaxisrotateylabel: '@', yaxisstaggerlabels: '@', yaxislabeldistance: '@', legendmargin: '&', legendwidth: '@', legendheight: '@', legendkey: '@', legendcolor: '&', legendalign: '@', legendrightalign: '@', legendupdatestate: '@', legendradiobuttonmode: '@', //angularjs specific objectequality: '@', //d3.js specific transitionduration: '@' }, controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs){ $scope.d3Call = function(data, chart){ checkElementID($scope, $attrs, $element, chart, data); }; }], link: function(scope, element, attrs){ scope.$watch('width + height', function() { updateDimensions(scope,attrs,element,scope.chart); }); scope.$watch('data', function(data){ if (data && angular.isDefined(scope.filtername) && angular.isDefined(scope.filtervalue)) { data = $filter(scope.filtername)(data, scope.filtervalue); } if(data){ //if the chart exists on the scope, do not call addGraph again, update data and call the chart. if(scope.chart){ return scope.d3Call(data, scope.chart); } nv.addGraph({ generate: function(){ initializeMargin(scope, attrs); var chart = nv.models.stackedAreaChart() .width(scope.width) .height(scope.height) .margin(scope.margin) .x(attrs.x === undefined ? function(d){ return d[0]; } : scope.x()) .y(attrs.y === undefined ? function(d){ return d[1]; } : scope.y()) .forceX(attrs.forcex === undefined ? [] : scope.$eval(attrs.forcex)) // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.) .forceY(attrs.forcey === undefined ? [0] : scope.$eval(attrs.forcey)) // List of numbers to Force into the Y scale .size(attrs.size === undefined ? function(d) { return (d.size === undefined ? 1 : d.size); } : scope.size()) .forceSize(attrs.forcesize === undefined ? [] : scope.$eval(attrs.forcesize)) // List of numbers to Force into the Size scale .showLegend(attrs.showlegend === undefined ? false : (attrs.showlegend === 'true')) .showControls(attrs.showcontrols === undefined ? false : (attrs.showcontrols === 'true')) .showXAxis(attrs.showxaxis === undefined ? false : (attrs.showxaxis === 'true')) .showYAxis(attrs.showyaxis === undefined ? false : (attrs.showyaxis === 'true')) .tooltips(attrs.tooltips === undefined ? false : (attrs.tooltips === 'true')) .noData(attrs.nodata === undefined ? 'No Data Available.' : scope.nodata) .interactive(attrs.interactive === undefined ? false : (attrs.interactive === 'true')) .clipEdge(attrs.clipedge === undefined ? false : (attrs.clipedge === 'true')) .color(attrs.color === undefined ? nv.utils.defaultColor() : scope.color()); if (attrs.useinteractiveguideline) { chart.useInteractiveGuideline(attrs.useinteractiveguideline === undefined ? false : (attrs.useinteractiveguideline === 'true')); } if(attrs.usevoronoi){ chart.useVoronoi((attrs.usevoronoi === 'true')); } if(attrs.style){ chart.style(attrs.style); } if(attrs.order){ chart.order(attrs.order); } if(attrs.offset){ chart.offset(attrs.offset); } if(attrs.interpolate){ chart.interpolate(attrs.interpolate); } if(attrs.tooltipcontent){ chart.tooltipContent(scope.tooltipcontent()); } if(attrs.xscale){ chart.xScale(scope.xscale()); } if(attrs.yscale){ chart.yScale(scope.yscale()); } if(attrs.xdomain){ if(Array.isArray(scope.$eval(attrs.xdomain))){ chart.xDomain(scope.$eval(attrs.xdomain)); } else if(typeof scope.xdomain() === 'function'){ chart.xDomain(scope.xdomain()); } } if(attrs.ydomain){ if(Array.isArray(scope.$eval(attrs.ydomain))){ chart.yDomain(scope.$eval(attrs.ydomain)); } else if(typeof scope.ydomain() === 'function'){ chart.yDomain(scope.ydomain()); } } if(attrs.sizedomain){ chart.sizeDomain(scope.sizedomain()); } scope.d3Call(data, chart); nv.utils.windowResize(chart.update); scope.chart = chart; return chart; }, callback: attrs.callback === undefined ? null : scope.callback() }); } }, (attrs.objectequality === undefined ? false : (attrs.objectequality === 'true'))); } }; }]) .directive('nvd3MultiBarChart', ['$filter', function($filter){ return { restrict: 'EA', scope: { data: '=', filtername: '=', filtervalue: '=', width: '@', height: '@', id: '@', showlegend: '@', tooltips: '@', tooltipcontent: '&', color: '&', showcontrols: '@', nodata: '@', reducexticks: '@', staggerlabels: '@', rotatelabels: '@', margin: '&', x: '&', y: '&', //forcex is not exposed in the nvd3 multibar.js file. it is not here on purpose. forcey: '@', delay: '@', stacked: '@', callback: '&', //xaxis showxaxis: '&', xaxisorient: '&', xaxisticks: '&', xaxistickvalues: '&xaxistickvalues', xaxisticksubdivide: '&', xaxisticksize: '&', xaxistickpadding: '&', xaxistickformat: '&', xaxislabel: '@', xaxisscale: '&', xaxisdomain: '&', xaxisrange: '&', xaxisrangeband: '&', xaxisrangebands: '&', xaxisshowmaxmin: '@', xaxishighlightzero: '@', xaxisrotatelabels: '@', xaxisrotateylabel: '@', xaxisstaggerlabels: '@', xaxisaxislabeldistance: '@', //yaxis showyaxis: '&', yaxisorient: '&', yaxisticks: '&', yaxistickvalues: '&yaxistickvalues', yaxisticksubdivide: '&', yaxisticksize: '&', yaxistickpadding: '&', yaxistickformat: '&', yaxislabel: '@', yaxisscale: '&', yaxisdomain: '&', yaxisrange: '&', yaxisrangeband: '&', yaxisrangebands: '&', yaxisshowmaxmin: '@', yaxishighlightzero: '@', yaxisrotatelabels: '@', yaxisrotateylabel: '@', yaxisstaggerlabels: '@', yaxislabeldistance: '@', legendmargin: '&', legendwidth: '@', legendheight: '@', legendkey: '@', legendcolor: '&', legendalign: '@', legendrightalign: '@', legendupdatestate: '@', legendradiobuttonmode: '@', //angularjs specific objectequality: '@', //d3.js specific transitionduration: '@' }, controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs){ $scope.d3Call = function(data, chart){ checkElementID($scope, $attrs, $element, chart, data); }; }], link: function(scope, element, attrs){ scope.$watch('width + height', function() { updateDimensions(scope,attrs,element,scope.chart); }); scope.$watch('data', function(data){ if (data && angular.isDefined(scope.filtername) && angular.isDefined(scope.filtervalue)) { data = $filter(scope.filtername)(data, scope.filtervalue); } if(data){ //if the chart exists on the scope, do not call addGraph again, update data and call the chart. if(scope.chart){ return scope.d3Call(data, scope.chart); } nv.addGraph({ generate: function(){ initializeMargin(scope, attrs); var chart = nv.models.multiBarChart() .width(scope.width) .height(scope.height) .margin(scope.margin) .x(attrs.x === undefined ? function(d){ return d[0]; } : scope.x()) .y(attrs.y === undefined ? function(d){ return d[1]; } : scope.y()) .forceY(attrs.forcey === undefined ? [0] : scope.$eval(attrs.forcey)) // List of numbers to Force into the Y scale .showLegend(attrs.showlegend === undefined ? false : (attrs.showlegend === 'true')) .showControls(attrs.showcontrols === undefined ? false : (attrs.showcontrols === 'true')) .showXAxis(attrs.showxaxis === undefined ? false : (attrs.showxaxis === 'true')) .showYAxis(attrs.showyaxis === undefined ? false : (attrs.showyaxis === 'true')) .tooltips(attrs.tooltips === undefined ? false : (attrs.tooltips === 'true')) .reduceXTicks(attrs.reducexticks === undefined ? false: (attrs.reducexticks === 'true')) .staggerLabels(attrs.staggerlabels === undefined ? false : (attrs.staggerlabels === 'true')) .noData(attrs.nodata === undefined ? 'No Data Available.' : scope.nodata) .rotateLabels(attrs.rotatelabels === undefined ? 0 : attrs.rotatelabels) .color(attrs.color === undefined ? nv.utils.defaultColor() : scope.color()) .delay(attrs.delay === undefined ? 1200 : attrs.delay) .stacked(attrs.stacked === undefined ? false : (attrs.stacked === 'true')); if(attrs.tooltipcontent){ chart.tooltipContent(scope.tooltipcontent()); } scope.d3Call(data, chart); nv.utils.windowResize(chart.update); scope.chart = chart; return chart; }, callback: attrs.callback === undefined ? null : scope.callback() }); } }, (attrs.objectequality === undefined ? false : (attrs.objectequality === 'true'))); } }; }]) .directive('nvd3DiscreteBarChart', ['$filter', function($filter){ return { restrict: 'EA', scope: { data: '=', filtername: '=', filtervalue: '=', width: '@', height: '@', id: '@', tooltips: '@', showxaxis: '@', showyaxis: '@', tooltipcontent: '&', staggerlabels: '@', color: '&', margin: '&', nodata: '@', x: '&', y: '&', //forcex is not exposed in the nvd3 multibar.js file. it is not here on purpose. forcey: '@', showvalues: '@', valueformat: '&', callback: '&', //xaxis xaxisorient: '&', xaxisticks: '&', xaxistickvalues: '&xaxistickvalues', xaxisticksubdivide: '&', xaxisticksize: '&', xaxistickpadding: '&', xaxistickformat: '&', xaxislabel: '@', xaxisscale: '&', xaxisdomain: '&', xaxisrange: '&', xaxisrangeband: '&', xaxisrangebands: '&', xaxisshowmaxmin: '@', xaxishighlightzero: '@', xaxisrotatelabels: '@', xaxisrotateylabel: '@', xaxisstaggerlabels: '@', xaxisaxislabeldistance: '@', //yaxis yaxisorient: '&', yaxisticks: '&', yaxistickvalues: '&yaxistickvalues', yaxisticksubdivide: '&', yaxisticksize: '&', yaxistickpadding: '&', yaxistickformat: '&', yaxislabel: '@', yaxisscale: '&', yaxisdomain: '&', yaxisrange: '&', yaxisrangeband: '&', yaxisrangebands: '&', yaxisshowmaxmin: '@', yaxishighlightzero: '@', yaxisrotatelabels: '@', yaxisrotateylabel: '@', yaxisstaggerlabels: '@', yaxislabeldistance: '@', legendmargin: '&', legendwidth: '@', legendheight: '@', legendkey: '@', legendcolor: '&', legendalign: '@', legendrightalign: '@', legendupdatestate: '@', legendradiobuttonmode: '@', //angularjs specific objectequality: '@', //d3.js specific transitionduration: '@' }, controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs){ $scope.d3Call = function(data, chart){ checkElementID($scope, $attrs, $element, chart, data); }; }], link: function(scope, element, attrs){ scope.$watch('width + height', function() { updateDimensions(scope,attrs,element,scope.chart); }); scope.$watch('data', function(data){ if (data && angular.isDefined(scope.filtername) && angular.isDefined(scope.filtervalue)) { data = $filter(scope.filtername)(data, scope.filtervalue); } if(data){ //if the chart exists on the scope, do not call addGraph again, update data and call the chart. if(scope.chart){ return scope.d3Call(data, scope.chart); } nv.addGraph({ generate: function(){ initializeMargin(scope, attrs); var chart = nv.models.discreteBarChart() .width(scope.width) .height(scope.height) .margin(scope.margin) .x(attrs.x === undefined ? function(d){ return d[0]; } : scope.x()) .y(attrs.y === undefined ? function(d){ return d[1]; } : scope.y()) .forceY(attrs.forcey === undefined ? [0] : scope.$eval(attrs.forcey)) // List of numbers to Force into the Y scale .showValues(attrs.showvalues === undefined ? false : (attrs.showvalues === 'true')) .tooltips(attrs.tooltips === undefined ? false : (attrs.tooltips === 'true')) .showXAxis(attrs.showxaxis === undefined ? false : (attrs.showxaxis === 'true')) .showYAxis(attrs.showyaxis === undefined ? false : (attrs.showyaxis === 'true')) .noData(attrs.nodata === undefined ? 'No Data Available.' : scope.nodata) .staggerLabels(attrs.staggerlabels === undefined ? false : (attrs.staggerlabels === 'true')) .color(attrs.color === undefined ? nv.utils.defaultColor() : scope.color()); if(attrs.tooltipcontent){ chart.tooltipContent(scope.tooltipcontent()); } if(attrs.valueformat){ chart.valueFormat(scope.valueformat()); } scope.d3Call(data, chart); nv.utils.windowResize(chart.update); scope.chart = chart; return chart; }, callback: attrs.callback === undefined ? null : scope.callback() }); } }, (attrs.objectequality === undefined ? false : (attrs.objectequality === 'true'))); } }; }]) .directive('nvd3HistoricalBarChart', ['$filter', function($filter){ return { restrict: 'EA', scope: { data: '=', filtername: '=', filtervalue: '=', width: '@', height: '@', id: '@', tooltips: '@', tooltipcontent: '&', color: '&', margin: '&', nodata: '@', x: '&', y: '&', // forcex: '@', forcey: '@', isarea: '@', interactive: '@', clipedge: '@', clipvoronoi: '@', interpolate: '@', highlightPoint: '@', clearHighlights: '@', callback: '&', useinteractiveguideline: '@', //xaxis xaxisorient: '&', xaxisticks: '&', xaxistickvalues: '&xaxistickvalues', xaxisticksubdivide: '&', xaxisticksize: '&', xaxistickpadding: '&', xaxistickformat: '&', xaxislabel: '@', xaxisscale: '&', xaxisdomain: '&', xaxisrange: '&', xaxisrangeband: '&', xaxisrangebands: '&', xaxisshowmaxmin: '@', xaxishighlightzero: '@', xaxisrotatelabels: '@', xaxisrotateylabel: '@', xaxisstaggerlabels: '@', xaxisaxislabeldistance: '@', //yaxis yaxisorient: '&', yaxisticks: '&', yaxistickvalues: '&yaxistickvalues', yaxisticksubdivide: '&', yaxisticksize: '&', yaxistickpadding: '&', yaxistickformat: '&', yaxislabel: '@', yaxisscale: '&', yaxisdomain: '&', yaxisrange: '&', yaxisrangeband: '&', yaxisrangebands: '&', yaxisshowmaxmin: '@', yaxishighlightzero: '@', yaxisrotatelabels: '@', yaxisrotateylabel: '@', yaxisstaggerlabels: '@', yaxislabeldistance: '@', legendmargin: '&', legendwidth: '@', legendheight: '@', legendkey: '@', legendcolor: '&', legendalign: '@', legendrightalign: '@', legendupdatestate: '@', legendradiobuttonmode: '@', //angularjs specific objectequality: '@', //d3.js specific transitionduration: '@' }, controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs){ $scope.d3Call = function(data, chart){ checkElementID($scope, $attrs, $element, chart, data); }; }], link: function(scope, element, attrs){ scope.$watch('width + height', function() { updateDimensions(scope,attrs,element,scope.chart); }); scope.$watch('data', function(data){ if (data && angular.isDefined(scope.filtername) && angular.isDefined(scope.filtervalue)) { data = $filter(scope.filtername)(data, scope.filtervalue); } if(data){ //if the chart exists on the scope, do not call addGraph again, update data and call the chart. if(scope.chart){ return scope.d3Call(data, scope.chart); } nv.addGraph({ generate: function(){ initializeMargin(scope, attrs); var chart = nv.models.historicalBarChart() .width(scope.width) .height(scope.height) .margin(scope.margin) .x(attrs.x === undefined ? function(d){ return d[0]; } : scope.x()) .y(attrs.y === undefined ? function(d){ return d[1]; } : scope.y()) .forceY(attrs.forcey === undefined ? [0] : scope.$eval(attrs.forcey)) // List of numbers to Force into the Y scale .tooltips(attrs.tooltips === undefined ? false : (attrs.tooltips === 'true')) .noData(attrs.nodata === undefined ? 'No Data Available.' : scope.nodata) .interactive(attrs.interactive === undefined ? false : (attrs.interactive === 'true')) .color(attrs.color === undefined ? nv.utils.defaultColor() : scope.color()); if (attrs.useinteractiveguideline) { chart.useInteractiveGuideline(attrs.useinteractiveguideline === undefined ? false : (attrs.useinteractiveguideline === 'true')); } if(attrs.tooltipcontent){ chart.tooltipContent(scope.tooltipcontent()); } if(attrs.valueformat){ chart.valueFormat(scope.valueformat()); } scope.d3Call(data, chart); nv.utils.windowResize(chart.update); scope.chart = chart; return