Angular-nvD3 Pie Chart Not Displaying - angularjs

I am trying to follow a simple example to make a pie chart but it does not render the chart. Even viewing the source, no chart code appears (only the original directive code). The controller is getting loaded as I do see the log file statement and the title property within the scope. I am not getting any errors to the console and a bit confused at the moment.
Thanks in advance
I am using the latest version of the libraries, added at the index.html file
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angularjs-nvd3-directives/0.0.7/angularjs-nvd3-directives.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.css"/>
Chart.html
<div >
<div ng-controller="chartsController" >
<div>
{{title}}
</div>
<nvd3ChartDirectives options="options" data="data" id="chartId" config="config" class="with-3d-shadow with-transitions">
</nvd3ChartDirectives>
</div>
</div>
Index.js
var app = angular.module('seApp', ['ngRoute', 'ngResource', 'ngMessages', 'ngAnimate', 'ui.bootstrap', 'smart-table', 'nvd3ChartDirectives']);
(Injecting as nvd3 does not work).
Chart.js
app.controller('chartsController', ['$scope', '$log', function($scope, $log) {
$scope.title = 'Chart Title';
$log.info ("Create Chart");
$scope.options = {
chart: {
type: 'pieChart',
height: 500,
width: 600,
x: function(d){return d.key;},
y: function(d){return d.y;},
showLabels: true,
transitionDuration: 500,
labelThreshold: 0.01,
legend: {
margin: {
top: 5,
right: 35,
bottom: 5,
left: 0
}
}
}
}
$scope.config = {
visible: true, // default: true
extended: false, // default: false
disabled: false, // default: false
autorefresh: true, // default: true
refreshDataOnly: false, // default: false
deepWatchOptions: true, // default: true
deepWatchData: false, // default: false
deepWatchConfig: true, // default: true
debounce: 10 // default: 10
};
$scope.xFunction = function(){
return function(d){
return d.key;
};
};
$scope.yFunction = function(){
return function(d){
return d.y;
};
};
$scope.data = [
{
key: "435fdfg",
y: 16
},
{
key: "fgfsgsg",
y: 12
},
{
key: "lodfrr",
y: 3
},
{
key: "yuiiyui",
y: 7
},
{
key: "adffd",
y: 4
}
]
}]);

I had a similar problem. After using ng-inspector I found out that the options where not passed in correctly due to a typo).
I did however tried to register the dependency with "nvd3ChartDirectives" but received an exception so I just used nvd3. Maybe this could be a possible problem.
I would recommend doing some debugging with ng-inspector or Batarang and check that the scope is set properly.
BTW, I'm using Angular 1.4.8.

Related

AngularJS $stateProvider URL results in blank page

I'm using angular-ui-router and set up a 2nd controller similar to my 1st one which was working, but the route in the 2nd controller is not properly routing the app. Can someone please tell me where I went wrong?
html for first controller (works properly):
<div style="height: 100%"> <!--took out: ng-if="map.center !== undefined"-->
<ui-gmap-google-map
center='map.center'
zoom='map.zoom'
draggable='map.draggable'
dragging='map.dragging'
refresh='map.refresh'
options='map.options'
events='map.events'
pan='map.pan'>
<ui-gmap-circle
center='map.circle.center'
radius='map.circle.radius'
fill='map.circle.fill'
stroke='map.circle.stroke'
clickable='map.circle.clickable'
draggable='map.circle.draggable'
editable='map.circle.editable'
visible='map.circle.visible'
events='map.circle.events'>
</ui-gmap-circle>
</ui-gmap-google-map>
<script src='//maps.googleapis.com/maps/api/js?key=AIzaSyD_g7xCYEi-U54SYfTXQ_lukRsChkWgjXQ'></script>
</div>
1st controller (works properly ):
(function (window, ng) {
ng.module('app', ['uiGmapgoogle-maps', 'ui.router'])
.config(function ($stateProvider) { //had: , $stateChangeError included in the function parameters, but that caused error
$stateProvider.state('searchRadius', {
url: '/:lat/:lon',
templateUrl: 'searchRadius.html', //changed from index to searchRadius.html
controller: 'MapsCtrl',
});
})
.controller('MapsCtrl', ['$scope', "uiGmapLogger", "uiGmapGoogleMapApi", "$interval", "$state", "$stateParams",
function ($scope, $log, GoogleMapApi, $interval, $state, $stateParams) {
$log.currentLevel = $log.LEVELS.debug;
var center = { latitude: parseFloat($stateParams.lat), longitude: parseFloat($stateParams.lon) };
alert(JSON.stringify(center));
Object.freeze(center); //caused TypeError: Cannot assign to read only property ('latitude') ...
console.log($stateParams);
$scope.map = {
center: center,
pan: false,
zoom: 16,
refresh: false,
events: {},
bounds: {}
};
$scope.map.circle = {
id: 1,
center: center,
radius: 500, //(current time - date lost)*km/hour
stroke: {
color: '#08B21F',
weight: 2,
opacity: 1
},
fill: {
color: '#08B21F',
opacity: 0.5
},
geodesic: false, // optional: defaults to false
draggable: false, // optional: defaults to false
clickable: true, // optional: defaults to true
editable: false, // optional: defaults to false
visible: true, // optional: defaults to true
events: {
dblclick: function () {
$log.debug("circle dblclick");
},
radius_changed: function (gObject) {
var radius = gObject.getRadius();
$log.debug("circle radius radius_changed " + radius);
}
}
}
//Increase Radius:
$interval(function(){
$scope.map.circle.radius += 30; //dynamic var
}, 1000); //end of interval function
} ]); //end of controller
})(window, angular);
2nd html (blank page):
<!--Add ability to input location as address-->
<div>
<ui-gmap-google-map
center='map.center'
zoom='map.zoom'
draggable='map.draggable'
dragging='map.dragging'
refresh='map.refresh'
options='map.options'
events='map.events'
pan='map.pan'>
<ui-gmap-circle
center='map.circle.center'
radius='map.circle.radius'
fill='map.circle.fill'
stroke='map.circle.stroke'
clickable='map.circle.clickable'
draggable='map.circle.draggable'
editable='map.circle.editable'
visible='map.circle.visible'
events='map.circle.events'>
</ui-gmap-circle>
</ui-gmap-google-map>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDWKJRXSux3dAdEYOYqjkoi2MCW8dutFbY&callback=initMap">
</script>
</div>
2nd controller (results in blank page with no errors):
(function (window, ng) {
ng.module('app', ['uiGmapgoogle-maps', 'ui.router'])
.config(function ($stateProvider) { //had: , $stateChangeError included in the function parameters, but that caused error
$stateProvider.state('getLocation', {
url: '/getLocation',
templateUrl: 'getlocation.html', //changed from index to searchRadius.html
controller: 'GetlocationCtrl',
});
})
.controller('GetlocationCtrl', ['$scope', "uiGmapLogger", "uiGmapGoogleMapApi", "$state", "$stateParams",
function ($scope, $log, GoogleMapApi, $state, $stateParams) {
$log.currentLevel = $log.LEVELS.debug;
var center = { latitude: 49.22, longitude: -122.66 }; //default center
alert(JSON.stringify(center));
console.log($stateParams);
$scope.map = {
center: center,
pan: false,
zoom: 16,
refresh: false,
events: {},
bounds: {}
};
$scope.map.circle = {
id: 1,
center: center,
radius: 500, //(current time - date lost)*km/hour
stroke: {
color: '#08B21F',
weight: 2,
opacity: 1
},
fill: {
color: '#08B21F',
opacity: 0.5
},
geodesic: false, // optional: defaults to false
draggable: false, // optional: defaults to false
clickable: true, // optional: defaults to true
editable: false, // optional: defaults to false
visible: true, // optional: defaults to true
events: {
dblclick: function () {
$log.debug("circle dblclick");
},
radius_changed: function (gObject) {
var radius = gObject.getRadius();
$log.debug("circle radius radius_changed " + radius);
}
}
}
} ]); //end of controller
})(window, angular);
(i) You are using $routerProvider which is not necessarily required
(ii) Also when i check your code, you are loading the first module after loading the 2nd controller. Place your scripts like this in index.html ,
<script src="searchRadius.js"></script>
<script src="getLoc.js"></script>

nvd3 AngularJS date format issue - non-epoch

I am using nvd3 chart in AngularJS. I am getting the data like series of [{"09/01/2015", 5},...]. i.e. [{mm/dd/yyyy, decimal}]. After checking NVD3 tutorial looks like date needs to be in epoch format, which is not possible for my case. I dont see any reference for that. How can make a line chart with Y axis some decimal values and X axis month-year or complete date without converting to epoch format.
Any reference or tutorial also would be a great help. Thanks in advance...
My Code:
var appCntrl = angular.module("AppCntrl",['nvd3']);
appCntrl.controller("QPBDController", function($scope){
$scope.score = {
"data":[7.97,8.93,6.53,4.87,4.98,4.56],
"term":["09/01/2015","10/01/2015","11/01/2015","12/01/2015","01/01/2016","02/01/2016"]
};
$scope.options = {
chart: {
type: 'lineChart',
height: 450,
margin : {
top: 20,
right: 20,
bottom: 40,
left: 55
},
x: function(d){ return d.x; },
y: function(d){ return d.y; },
useInteractiveGuideline: true,
dispatch: {
stateChange: function(e){ console.log("stateChange"); },
changeState: function(e){ console.log("changeState"); },
tooltipShow: function(e){ console.log("tooltipShow"); },
tooltipHide: function(e){ console.log("tooltipHide"); }
},
xAxis: {
tickFormat: function(d) {return d3.time.format("%b %d, %Y")(d);}
},
yAxis: {
axisLabel: 'Voltage (v)',
tickFormat: function(d){
return d3.format('.02f')(d);
},
axisLabelDistance: -10
},
callback: function(chart){
console.log("!!! lineChart callback !!!");
}
},
title: {
enable: true,
text: 'Title for Line Chart'
},
subtitle: {
enable: true,
text: 'Subtitle for simple line chart.',
css: {
'text-align': 'center',
'margin': '10px 13px 0px 7px'
}
},
caption: {
enable: true,
html: '<b>Figure 1.</b> .',
css: {
'text-align': 'justify',
'margin': '10px 13px 0px 7px'
}
}
};
$scope.data = sinAndCos();
var str = ["s"];
/*Random Data Generator */
function sinAndCos() {
var sin = [],sin2 = [],
cos = [];
//Data is represented as an array of {x,y} pairs.
for (var i = 0; i < $scope.score.term.length; i++) {
sin.push({x: $scope.score.term[i], y: $scope.score.data[i]});
sin2.push({x: $scope.score.term[i], y: $scope.score.data[i]});
cos.push({x: $scope.score.term[i], y: $scope.score.data[i]});
}
console.log(sin);
//Line chart data should be sent as an array of series objects.
return [
{
values: sin, //values - represents the array of {x,y} data points
key: 'Sine Wave', //key - the name of the series.
color: '#ff7f0e', //color - optional: choose your own line color.
strokeWidth: 2,
classed: 'dashed'
},
{
values: cos,
key: 'Cosine Wave',
color: '#2ca02c'
},
{
values: sin2,
key: 'Another sine wave',
color: '#7777ff',
area: true //area - set to true if you want this line to turn into a filled area chart.
}
];
};
});
index.html:
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="css/app.css" rel="stylesheet">
<script src="node_modules/angular/angular.min.js"></script>
<script src="node_modules/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="node_modules/d3/d3.min.js"></script>
<script src="node_modules/nvd3/build/nv.d3.min.js"></script>
<script src="node_modules/angular-nvd3/dist/angular-nvd3.min.js"></script>
<link href="node_modules/nvd3/build/nv.d3.min.css" rel="stylesheet">
<script src="bizkpi.js"></script>
<script src="js/controllers.js"></script>
<nvd3 options="options" data="data"></nvd3>
The above code shows an error in console like below and nothing comes up in GUI
TypeError: n.getMonth is not a function
at Yn.A.b (d3.min.js:1)
at t (d3.min.js:1)
at SVGTextElement.$scope.options.chart.xAxis.tickFormat (controllers.js:29)
at SVGTextElement.arguments.length.each.function.n.textContent (d3.min.js:3)
at d3.min.js:3
at Y (d3.min.js:1)
at Array.Co.each (d3.min.js:3)
at Array.Co.text (d3.min.js:3)
at SVGGElement.<anonymous> (d3.min.js:5)
you will have to format the date as follows:
vm.chart.options.chart.xAxis.tickFormat = function(d) {return d3.time.format("%b %d, %Y")(d);};
in your options.chart you should have :
lines: {
xScale: d3.time.scale(),
},
I think you should set the ticks and tickValues as well for example..
vm.chart.options.chart.xAxis.ticks = d3.time.monday;
vm.chart.options.chart.xAxis.tickValues = function(d) {return d3.time.monday.range(from, to, 2);};
};

Error: ng:areq Bad Argument ANGULAR

I am developing an Angularjs application.
I am using ocLazyLoad and ui.router.
I have a controller and two views with graphs using chart.js and angular-nvd3.
The graphics appear but keeps giving this mistake:
Error: ng:areq Bad Argument
and
angular.js:13550 Error: [ng:areq] http://errors.angularjs.org/1.5.5/ng/areq?p0=ChartCtrl&p1=not%20aNaNunction%2C%20got%20undefined
at Error (native)
MY app.js::
.state('dashboard.chart',{
templateUrl:'views/chart.html',
url:'/chart',
controller:'ChartCtrl',
resolve: {
loadMyFile:function($ocLazyLoad) {
return $ocLazyLoad.load({
name:'chart.js',
files:[
'bower_components/angular-chart.js/dist/angular-chart.min.js',
'bower_components/angular-chart.js/dist/angular-chart.css'
]
}),
$ocLazyLoad.load({
name:'sbAdminApp',
files:['scripts/controllers/chartContoller.js']
})
}
}
})
.state('dashboard.graficohora',{
templateUrl:'views/graficohora.html',
url:'/graficohora',
controller:'GraficohoraCtrl',
resolve: {
loadMyFile:function($ocLazyLoad) {
return $ocLazyLoad.load({
name:'nvd3',
files:[
'bower_components/d3/d3.js',
'bower_components/nvd3/build/nv.d3.js',
'bower_components/angular-nvd3/dist/angular-nvd3.js',
]
}),
$ocLazyLoad.load({
name:'sbAdminApp',
files:['scripts/controllers/graficohoraController.js']
})
}
}
MY CONTROLLER::
angular.module('sbAdminApp')
.controller('GraficohoraCtrl', ['$scope', '$timeout', function ($scope, $timeout) {
$scope.options = {
chart: {
type: 'pieChart',
height: 500,
x: function(d){return d.key;},
y: function(d){return d.y;},
showLabels: true,
duration: 500,
labelThreshold: 0.01,
labelSunbeamLayout: true,
legend: {
margin: {
top: 5,
right: 35,
bottom: 5,
left: 0
}
}
}
};
getData()
function getData(){
$scope.data = [
{
key: "One",
y: 5
},
{
key: "Two",
y: 2
},
{
key: "Three",
y: 9
},
{
key: "Four",
y: 7
},
{
key: "Five",
y: 4
},
{
key: "Six",
y: 3
},
{
key: "Seven",
y: .5
}
];
}
}]);
MY HTML::
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Charts</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<div class="row">
<div class="col-lg-12 col-sm-12" id="polar area-chart" ng-controller="ChartCtrl">
<div class="panel panel-default">
<div class="panel-heading">Informações sobre Dados Analisados</div>
<div class="panel-body">
<div ng-controller="ChartCtrl">
<nvd3 options='options' data='data'></nvd3>
</div>
</div>
</div>
</div>
</div>
Can you please help me with this error?
thanks..
The ng-controller on the html file was on the wrong place causing this error.
You never define the 'ChartCtrl' in your app module.
Add this to your app module.
.controller('ChartCtrl',['$scope', function ($scope) {
// add functionality to your controller
}]);

UI Grid column defs get overridden

On populating the UI Grid, the UI Grid column defs get overridden when the data has more fields. How to solve this? Where and how to solve this, in the controller, in the WEB Api ?
For simplicity no filtering in the sample is put:
<!-- View -->
<style>
.myGrid { height: 300px; width: 1000px; border: 1px solid black;}
</style>
<div id="grid1" ui-grid="grid1Options"
class="myGrid" ui-grid-resize-columns ui-grid-move-column ui-grid-pinning
ui-grid-edit ui-grid-cellNav ui-grid-selection ui-grid-save-state>
</div>
//Controller
(function () {
'use strict';
angular
.module('pdb').controller('suppliersController_',
['$scope', '$http', 'uiGridConstants', '$resource', 'suppliersFactory_',
fSuppliersController_]);
function fSuppliersController_($scope, $http, uiGridConstants, $resource, suppliersFactory_)
{
$scope.grid1Options = {
enableSorting: true, enableFiltering: false, showGridFooter: false,
showColumnFooter: false, enableColumnResizing: true, enableColumnMoving: true,
enableCellEditOnFocus: true, enableRowSelection: true, enableSelectAll: true,
selectionRowHeaderWidth: 35,
columndefs: [
{ name: 'Name_Supplier', width: '40%', displayName: 'Supplier', field: 'Name_Supplier' },
{ name: 'Contact', width: '60%', displayName: 'Contact', field: 'Contact' }
]};
(new suppliersFactory_())
.$getAll()
.then(function (result) { $scope.grid1Options.data = result.value; });
}
})();
// Factory
(function () {
'use strict';
angular.module('pdb').factory('suppliersFactory_',
['$resource', fSuppliersFactory_]);
function fSuppliersFactory_($resource) {
return $resource("", {}, { 'getAll': { method: "GET", url: "odata/Suppliers" } });
}
})();
// Web API returns more fields..
public class SuppliersController : ODataController
{
private PDBEntities db = new PDBEntities();
// GET: odata/Suppliers
[EnableQuery]
public IQueryable<tblSupplier> GetSuppliers() { return db.tblSuppliers; }
}
https://github.com/angular-ui/ui-grid/commit/fd154a71f6a7407bce577efebde9f1122274c48b
Make sure you have grid.lateBoundColumns set to false.
This is an old issue, make sure you have a recent version of ng-grid.
From the author:
I see what the issue is,
There is no data and no column definitions initially , so the grid
goes into a "waiting" state and has a flag set to automatically
generate the columns, then, even when you set the column definitions,
they get auto-generated when the data hits. I added a fix for it in
commit
https://github.com/angular-ui/ui-grid/issues/285
http://jsfiddle.net/ShEB4/9/

make zoom using nvd3

I need make zoom in graphic. I am using angular js and nvd3.
this is a part of my Code, html and angular module:
var app = angular.module('DL', ['nvd3']);
app.controller('daCtrl', function($scope) {
$scope.graphic = [{key: "a", values: [[243434, 1],[363352, 2],...]}, [[243434, 1],[363352, 2],...]},... ];
$scope.options = {
chart: {
type: "lineChart",
height: 450,
margin : {
top: 20,
right: 20,
bottom: 60,
left: 65
},
x: function(d){ return d[0]; },
y: function(d){ return d[1]/100; },
average: function(d) { return d.mean/100; },
color: d3.scale.category10().range(),
transitionDuration: 300,
useInteractiveGuideline: true,
clipVoronoi: false,
xAxis: {
axisLabel: 'Date',
tickFormat: function(d) {
return d3.time.format('%m/%d/%y')(new Date(d));
}
},
yAxis: {
axisLabel: 'Measure',
tickFormat: function(d){
return d3.format('.02f')(d);
},
axisLabelDistance: 20,
showMaxMin: true,
staggerLabels: true
}
}
};
});
<link rel="stylesheet" type="text/css" href="../bower_components/nvd3/nv.d3.css">
<script src="../bower_components/d3/d3.js"></script>
<script src="../bower_components/nvd3/nv.d3.js"></script>
<script src="../bower_components/angular-nvd3/dist/angular-nvd3.js"></script>
<nvd3 options="options" data="graphic"></nvd3>
The graphic is ok, but I need make zoom over the graphic.
I've seen that D3 is possible, but not if you can with equally nvd3
Try to use a lineWithFocusChart instead of lineChart and then add this options to your chart:
x2Axis: {
tickFormat: function (d) {
return d3.time.format('%m/%d/%y')(new Date(d));
}
},
y2Axis: {
tickFormat: function(d){
return d3.format('.02f')(d);
}
}
I know that I am two years late to the party but zooming in angularjs is totally a thing, just add something like:
zoom: {
enabled: true,
scaleExtent: [1, 10000],
useFixedDomain: false,
useNiceScale: false,
horizontalOff: false,
verticalOff: true,
unzoomEventType: "dblclick.zoom"
}
To your chart options
I changed nvd3 to dygraph using Dygraphs angularjs Directive (https://twittstrap.com/dygraphs-angularjs-directive/)
Now (the same example of website)
HTML:
<head>
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bower_components/dygraphs/dygraph-combined.js"></script>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
<script src="bower_components/moment/moment.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="bower_components/angular-dygraphs/src/angular-dygraphs.js"></script>
<!--<link rel="stylesheet" type="text/css" href="bower_components/angular-dygraphs/demo/demo.css"/>-->
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
</head>
<body ng-app="demoApp">
<div ng-controller="DemoCtrl">
<ng-dygraphs data="graph.data" options="graph.options" legend="graph.legend"></ng-dygraphs>
<div>
</body>
js:
var example = angular.module('demoApp', [
"angular-dygraphs"
]);
demoApp.controller('DemoCtrl', function ($scope) {
$scope.graph = {
data: [
],
options: {
labels: ["x", "A", "B"]
},
legend: {
series: {
A: {
label: "Series A"
},
B: {
label: "Series B",
format: 3
}
}
}
};
var base_time = Date.parse("2008/07/01");
var num = 24 * 0.25 * 365;
for (var i = 0; i < num; i++) {
$scope.graph.data.push([ new Date(base_time + i * 3600 * 1000),
i + 50 * (i % 60), // line
i * (num - i) * 4.0 / num // parabola
]);
}
});

Resources