different nvD3 approaches - angularjs

As I am relatively new to nvD3, I am confused with the different nvD3 code notations I am coming across, can any one help me to understand it better.
The nvD3 code samples are as follows:
Aprroach#1:
html :
<div id="chart">
<svg></svg>
</div>
script :
nv.addGraph(function() {
var chart = nv.models.lineChart()
.useInteractiveGuideline(true)
;
chart.xAxis
.axisLabel('Time (ms)')
.tickFormat(d3.format(',r'))
;
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(d3.format('.02f'))
;
var data=sinandcos();
d3.select('#chart svg')
.datum(sinandcos())
.transition().duration(500)
.call(chart)
.selectAll('.nv-y text')
.attr('x',-15)
;
return chart;
});
Approach #2 :
html :
<body ng-controller="MainCtrl">
<nvd3 options="options" data="data"></nvd3>
</body>
script :
var app = angular.module('myApp', ['nvd3']);
app.controller('MainCtrl', function($scope, $compile) {
$scope.options = {
chart: {
type: 'lineChart',
height: 450,
margin : {
"top": 20,
"right": 20,
"bottom": 40,
"left": 55
},
x: function(d){ return d[0]; },
y: function(d){ return d[1]; },
useVoronoi: false,
clipEdge: true,
transitionDuration: 2000,
useInteractiveGuideline: true,
xAxis: {
tickFormat: function(d) {
return d3.time.format('%x')(new Date(d))
},
showMaxMin: false
},
yAxis: {
tickFormat: function(d){
return d3.format('.02f')(d);
}
}
}
};
$scope.data = [....]
});
In Approach #1, I don't see any angular js controllers concept and in Approach #2, I don't see chart drawing calls like the below to draw the chart
d3.select('#chart svg')
.datum(sinandcos())
.transition().duration(500)
.call(chart)
.selectAll('.nv-y text')
.attr('x',-15)
In Approach#2, if I want to add 4 charts in a single page, as below, how can I do it? Can any one point some reference code for this?
chart1# chart2#
Chart3# chart4#

I believe you are confusing the nvD3 library (#1) with a library such as Angular-nvD3 built on top of the nvD3 library (#2).
To add 4 charts to a page, you could create 4 containers in the arrangement you want and then repeat the nv.addGraph for each of them to add the graphs.
The Approach #1 would look like:
html :
<div id="chart1">
<svg></svg>
</div>
<div id="chart2">
<svg></svg>
</div>
<div id="chart3">
<svg></svg>
</div>
<div id="chart4">
<svg></svg>
</div>
script :
nv.addGraph(function() {
...
d3.select('#chart1 svg')
...
}
nv.addGraph(function() {
...
d3.select('#chart2 svg')
...
}
nv.addGraph(function() {
...
d3.select('#chart3 svg')
...
}
nv.addGraph(function() {
...
d3.select('#chart4 svg')
...
}

Related

AngularJS: Route displaying blank page

I have a route/view that is displaying a blank page. I am pretty sure it was working the way I have it right now a few days ago which leads me to think it is a problem with my Google Maps API key, but there are no errors or warnings so I think it has to do with my routing setup. But I have another view set up exactly the same way and that one does work...
Broken view: http://alainwebdesign.ca/pl2/#/49.2/-122.66
Working view: http://alainwebdesign.ca/pl2/#/getLocation
Controller (I commented out the.config for Google Map API because I have a script reference in my view searchRadius.html) :
(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',
});
})
////ALREADY HAVE GOOGLE MAPS KEY ON searchRadius.html
.config(['uiGmapGoogleMapApiProvider', function (GoogleMapApi) {
GoogleMapApi.configure({
key: 'AIzaSyC_XEbbw3sNm4XlLAgqMJTggeHLDUdV-pY',
v: '3',
libraries: 'weather,geometry,visualization'
});
} ])
.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);
searchRadius.html:
<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=AIzaSyC_XEbbw3sNm4XlLAgqMJTggeHLDUdV-pY'></script>
</div>
Combine the 2 files into 1 file and initialize the $stateProvider in a single line.

How do i update the title option in an angular-nv3d piechart

I am using nvd3 piechart to show the size of the overall files in a folder.
my question is how to update the title of the chart after each data update is happening (for example to show the overall size in the title.
i tried using an object in the scope which does update with the currect size, but it does not update in the title option in the chart)
here is my code:
app.controller("chartCtrl", function($scope, foldersSrvc){
$scope.options = {
chart: {
type: "pieChart",
height: 400,
showLabels: true,
labelType: "value",
title: "Content(" + $scope.filesSize + ")",
labelSunbeamLayout: true,
x: function(d){return d.type;},
y: function(d){return d.size;},
donut: true
}
};
foldersSrvc.getFiles("server").then(function(data){
$scope.data = data;
$scope.filesSize = foldersSrvc.getFilesSize(data);
});
$scope.$on('folderClicked', function(event, args){
foldersSrvc.getFiles(args.id).then(function(data){
$scope.data = data;
$scope.filesSize = foldersSrvc.getFilesSize(data);
});
})
})
I recommend the angular wrapper for nvd3, angular-nvd3 to support data binding.
angular.module('myApp', ['nvd3'])
.controller('myCtrl', function($scope){
/* Chart options */
$scope.options = { /* JSON data */ };
/* Chart data */
$scope.data = { /* JSON data */ }
})
html
<div ng-app="myApp">
<div ng-controller="myCtrl">
<nvd3 options="options" data="data"></nvd3>
</div>
</div>

Angular NvD3 Multichart is not working

I want to create Multichart graph with Line and MultiBar Chart by using Angularjs NvD3. I have to create Line graph but unable to showing Multibar chart, i think i make some mistake. Here is plunker
var app = angular.module('plunker', ['nvd3']);
app.controller('MainCtrl', function($scope) {
$scope.options = {
chart: {
type: 'multiChart',
height: 450,
margin : {
top: 30,
right: 60,
bottom: 50,
left: 70
},
color: d3.scale.category10().range(),
//useInteractiveGuideline: true,
duration: 500,
xAxis: {
tickFormat: function(d){
return d3.format(',f')(d);
}
},
yAxis1: {
tickFormat: function(d){
return d3.format(',.1f')(d);
}
},
yAxis2: {
tickFormat: function(d){
return d3.format(',.1f')(d);
}
}
}
};
/***********Line*********/
$scope.data = [];
$scope.data[0]={};
$scope.data[0].key='Stream';
$scope.data[0].yAxis=1;
$scope.data[0].type='line';
$scope.data[0].values=[];
$scope.data[0].values[0]={};
$scope.data[0].values[0].x=0;
$scope.data[0].values[0].y=4;
$scope.data[0].values[1]={};
$scope.data[0].values[1].x=1;
$scope.data[0].values[1].y=8;
$scope.data[1]={};
$scope.data[1].key='Stream2';
$scope.data[1].yAxis=1;
$scope.data[1].type='line';
$scope.data[1].values=[];
$scope.data[1].values[0]={};
$scope.data[1].values[0].x=0;
$scope.data[1].values[0].y=4;
$scope.data[1].values[1]={};
$scope.data[1].values[1].x=1;
$scope.data[1].values[1].y=8;
/*******************************/
/********MultiBar Chart**********/
$scope.data[2]={};
$scope.data[2].key='Stream3';
$scope.data[2].yAxis=2;
$scope.data[2].type='multiBarChart';
$scope.data[2].values=[];
$scope.data[2].values[0]={};
$scope.data[2].values[0].key="Stream0";
$scope.data[2].values[0].values=[];
$scope.data[2].values[0].values[0]={};
$scope.data[2].values[0].values[0].key="Stream0";
$scope.data[2].values[0].values[0].series=0;
$scope.data[2].values[0].values[0].x=0;
$scope.data[2].values[0].values[0].y=5;
$scope.data[2].values[1]={};
$scope.data[2].values[1].key="Stream1";
$scope.data[2].values[1].values=[];
$scope.data[2].values[1].values[0]={};
$scope.data[2].values[1].values[0].key="Stream1";
$scope.data[2].values[1].values[0].series=1;
$scope.data[2].values[1].values[0].x=0;
$scope.data[2].values[1].values[0].y=4;
/*********************************/
console.log($scope.data);
});
please find below plunkr with
'multichart with configurable tooltip, conditional points highlight,area chart, bar chart and line chart
plunk in comments

How to copy selction into a new ui-grid

I am using Angular ui-grid (from ui-grid.info).
I have one ui-grid showing JSON Data delivered by a webapi-controller what works perfectly.
I added a second ui-grid with the same columsDef but no data.
I want to copy the (multi-)selected rows from grid1 to grid 2 using a button.
How would I access the selection to add it into the data of the second grid?
app.js
var app = angular.module('app', ['ui.grid', 'ui.grid.grouping','ui.grid.selection']);
app.controller('MainCtrl', ['$scope', '$http', '$log', 'i18nService', '$interval', 'uiGridGroupingConstants', function ($scope, $http, $log,i18NService, $interval, uiGridGroupingConstants) {
$scope.langs = i18NService.getAllLangs();
$scope.lang = 'de';
i18NService.setCurrentLang('de');
$scope.gridOptions = {
rowSelection:true,
enableFiltering: true,
enableRowSelection: true,
enableFullRowSelection :true,
enableSelectAll: true,
selectionRowHeaderWidth: 35,
rowHeight: 75,
showGridFooter:true,
treeRowHeaderAlwaysVisible: true,
columnDefs: [
{ name: 'Trigraph',field:'ZeigeTrigraphen',width:'10%'},
{ name: 'Titel', field: 'Titel', cellTemplate: '<td style="word-wrap:break-word;padding:5px;">{{ COL_FIELD }}</td>' },
{ name: 'Ziel', field: 'Ziel', cellTemplate: '<td style="word-wrap:break-word;padding:5px;">{{ COL_FIELD }}</td>' },
],
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
}
};
i18NService.setCurrentLang('de');
$http.get('/api/Alarmkalender/HoleAlle').then(function (resp) {
$scope.gridOptions.data = resp.data;
$log.info(resp);
});
html
<div class="container" ng-app="app">
#*<link rel="styleSheet" href="../../Scripts/ui-grid/ui-grid.min.css" />*#
<style>
.grid {
width: auto;
height: 350px;
}
</style>
<h2>Alarmmassnahmen</h2>
<div ng-controller="MainCtrl">
<div id="grid1" ui-grid="gridOptions" ui-grid-grouping class="grid"></div>
<button name="SpeichernButton" class="btn btn-success" id="btnSpeichern" type="submit" value="SpeichernButton"><i class="glyphicon glyphicon-save"></i> In Alarmkalender kopieren</button>
<div id="grid2" ui-grid="gridOptions2" class="grid"></div>
</div>
There are several ways to achieve your goal. I made a Plunker to demonstrate a possible solution.
You could create an ng-click on the row-template and gather all row selections. You either instantly load them into the new grid (as shown in Plunker) or load them all on external button-click.
There are basically three steps
First modify the row-Template
$templateCache.put('ui-grid/uiGridViewport',
...
"<div ng-repeat=\"(rowRenderIndex, row) in rowContainer.renderedRows track by $index\"" +
"ng-click=\"grid.appScope.addRowtoSelection(row)\"" +
...
);
Then you bind that addRowtoSelection() to your first grid and push selected rows into an array.
all.relectedRows = [];
all.gridOptions = {
...
appScopeProvider : {
addRowtoSelection : function(row) {
all.relectedRows.push(row.entity);
},
},
};
Finally you bind that array as new data to your second grid.
all.gridOptionsTwo = {
data: 'all.relectedRows',
...
};
e: If you want to use a button instead of instant addition of rows, you could use selectedRows as temporary array and reference selectedRowsData in your second grid. See updated Plunker.
HTML
<button ng-click="all.addRowsToSecondGrid();">Add Rows</button>
JavaScript
all.relectedRowsData = [];
all.addRowsToSecondGrid = addRowsToSecondGrid;
function addRowsToSecondGrid() {
all.relectedRowsData = [];
all.relectedRowsData = all.relectedRowsData.concat(all.relectedRows);
}
all.gridOptionsTwo = {
data: 'all.relectedRowsData',
...
Hopefully that helps.

Angular JS animation not working, (using ngAnimate and TweenMax)

ok, here is my code:
(function(){
//Define angular main module - module -
var app = angular.module('module', ['ngAnimate']);
//Define controller -TimeLine-
app.controller('TimeLine', function(){
this.initialize = true;
});
//Define controller -PersonalGravatar-
app.controller('PersonalGravatar', function(){
this.email = "mail#gmail.com";
this.getImage = function(email) {
// MD5 (Message-Digest Algorithm) by WebToolkit
var size = size || 460;
return 'http://www.gravatar.com/avatar/' + MD5(email) + '.jpg?s=' + size;
};
});
//Define animation - gravatar-
app.animation(".gravatar", function() {
console.log("im displaying correctly");
//that's it, this next 'return' is not working.
return {
console.log("im NOT displaying in console");
enter: function(element, done){
TweenMax.to(element, 2, { css:{left:500, onComplete:done} } );
},
leave: function(element, done){
// TweenMax.to(element, 2, { css:{left:500, onComplete:done} } );
}
};
});
})();
then my html code is:
<html class="no-js" ng-app="module">
... more code ...
<div id="app-main-container" ng-controller="TimeLine as animations">
<div id="gravatar" class="gravatar" ng-controller="PersonalGravatar as gravatar"
ng-if="animations.initialize">
<img ng-src="{{gravatar.getImage(gravatar.email)}}" alt="">
</div>
</div> <!-- /app main container -->
<script src="../1.2.18/angular.min.js"></script>
<cript src="../1.2.18/angular-animate.min.js"> </script>
<script src="../1.12.1/TweenMax.min.js"></script>
<script src="js/main.js"></script>
so I'm new in angularJS, I don't no why app.animation is not returning any animation.. thanks a LOT!!
Just $timeout...
app.controller('TimeLine', function($scope, $timeout){
return $timeout(function() {
$scope.initialize = true;
}, 100);
});
I created a Plunk of your example animating the enter and leave.
Notice how you no longer need to wrap your CSS properties in a css object.
enter: function(element, done){
TweenMax.from(element, 1, {x:500, autoAlpha: 0, scale: 0.5, onComplete:done});
},
leave: function(element, done){
TweenMax.to(element, 1, {x:500, autoAlpha: 0, scale: 0.5, onComplete:done});
}
Plunker http://plnkr.co/edit/6tQFdA?p=preview

Resources