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>
Related
I have events came from the database. Fullcalendar is working fine but how to remove all events in click button. My main goal is to reset all event when i need to. Is this possible or any other ways to achieve this goal. Im new to angular js. really appreciate your help. thanks in advance
html
<div class="content-panel" ng-controller="Controller">
<div ui-calendar="uiConfig.calendar" class="span8 calendar" ng-model="eventSources" calendar="myCalendar"></div>
<button type="button" ng-click="removeallevents()">Remove all Event</button>
</div>
js
var app = angular.module('app', ['ui.calendar']);
app.controller('Controller', function($scope, $http ,$timeout){
$scope.events = [];
$scope.myevents = function(start, end, timezone, callback) {
$scope.loaderForm=true;
var formdata = $scope.data;
$http.post("EventsDate.php", formdata).then(function (response) {
var events = [];
var data = response.data;
angular.forEach(data, function(value, key){
$scope.events.push({
id: value.ID,
title: value.titleEvent,
start: value.dateEvent
});
});
callback(events);
$scope.loaderForm=false;
});
}
$scope.removeallevents = function() {
//function to remove all events
}
$scope.uiConfig = {
calendar:{
editable: true,
header:{
left: 'title',
center: '',
right: 'today prev,next'
},
dayClick: $scope.addEvent
}
};
$scope.eventSources = [$scope.events,$scope.myevents];
});
Yes, it's posible usign full calendar function to remove events:
.fullCalendar('removeEvents');
You can find more info here
I have a requirement to create a multiselect dropdown using angularjs with values coming from database based on different parameters.I have implemented following code. It is working fine when the page loads at first time. If come to this page second time, the $http.get function is not executing and still showing the same data as in the first page load.
This is my .js file:
var app = angular.module("myModule", ["angularjs-dropdown-multiselect"]);
app.controller("myController", ['$scope','$http', function ($scope,$http) {
$scope.AllDescriptions = [];
$scope.DescriptionsSelected = [];
$scope.dropdownSetting = {
scrollable: true,
scrollableHeight: '200px'
};
$http.get('/Areaname/ControllerName/MethodName').then(function (data) {
angular.forEach(data.data, function (value, index) {
$scope.AllDescriptions.push({ id: value, label: value });
});
});
}])
This is my html file :
<div ng-app="myModule" ng-controller="myController" >
<div class="container">
<div id="divRight" style="min-height:5px;display: inline-block; width: 40%; vertical-align: top;">
<label style="float:left;">Error Description : </label>
<div style="float:left;width:200px;margin-left:10px" ng-dropdown-multiselect="" extra-settings="dropdownSetting" options="AllDescriptions" selected-model="DescriptionsSelected" checkboxes="true"></div>
</div>
</div>
</div>
This is my .cs file :
public JsonResult MethodName()
{
List<string> errorDescriptions = //Get from server
return new JsonResult() { Data=errorDescriptions,JsonRequestBehavior=JsonRequestBehavior.AllowGet};
}
Kindly help me to execute this JSON method for every page request instead of only in the first page request. Thank you.
I think the problem is with cache. Try to put your get method in variable ($scope.GetDescriptions = function () { $http.get... }) and use ng-init directive
(<div class="container" ng-init="GetDescriptions()">). Also try to empty array before push elements in it ($scope.AllDescriptions = [], $scope.AllDescriptions.push(...)
Try adding $route.reload(), this reinitialise the controllers but not the services:
app.controller("myController", ['$scope','$http','$route' function ($scope,$http,$route) {
$route.reload(); // try pass parameter true to force
$scope.AllDescriptions = [];
$scope.DescriptionsSelected = [];
$scope.dropdownSetting = {
scrollable: true,
scrollableHeight: '200px'
};
$http.get('/Areaname/ControllerName/MethodName').then(function (data) {
angular.forEach(data.data, function (value, index) {
$scope.AllDescriptions.push({ id: value, label: value });
});
});
}])
If you want to reset the whole state of your application you can use $window.location.reload(); instead route like:
app.controller("myController", ['$scope','$http','$route' function ($scope,$http,$route) {
$window.location.reload(); // try pass parameter true to force
$scope.AllDescriptions = [];
$scope.DescriptionsSelected = [];
$scope.dropdownSetting = {
scrollable: true,
scrollableHeight: '200px'
};
$http.get('/Areaname/ControllerName/MethodName').then(function (data) {
angular.forEach(data.data, function (value, index) {
$scope.AllDescriptions.push({ id: value, label: value });
});
});
}])
Hope this works.
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.
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')
...
}
How do I get ng-grid to auto resize its height based on the page size? The documentation on ng-grid's site uses a fixed height. The best solution I've seen comes from this link:
.ngViewport.ng-scope {
height: auto !important;
overflow-y: hidden;
}
.ngTopPanel.ng-scope, .ngHeaderContainer {
width: auto !important;
}
This does not work with server-side paging. I've copied the server-side paging example from ng-grid's site, and applied the css above, but as you can see, only the first 6 rows are shown: http://plnkr.co/edit/d9t5JvebRjUxZoHNqD7K?p=preview
And { height: 100% } does not work...
You can try using the ng-grid Flexible Height Plugin, all you need to do is add this plugin to the plugins property in grid options and he'll take care of the rest .
Example:
$scope.gridOptions = {
data: 'myData',
enablePaging: true,
showFooter: true,
totalServerItems: 'totalServerItems',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions,
plugins: [new ngGridFlexibleHeightPlugin()]
};
Live example: http://plnkr.co/edit/zNHhsEVqmpQmFWrJV1KQ?p=preview
If you don't want to add any plugins I've implemented an easy solution to dynamically change the table's height strictly based on the visible rows. I am using Ui-Grid-Unstable v3.0. No need to touch CSS.
My HTML looks like:
<div id="grid1" ui-grid="gridOptions" ui-grid-grouping ui-grid-exporter class="grid"></div>
In your controller add:
$scope.$watch('gridApi.core.getVisibleRows().length', function() {
if ($scope.gridApi) {
$scope.gridApi.core.refresh();
var row_height = 30;
var header_height = 31;
var height = row_height * $scope.gridApi.core.getVisibleRows().length + header_height;
$('.grid').height(height);
$scope.gridApi.grid.handleWindowResize();
}
});
And to turn off scrolling add the following line where gridOptions is initialized:
enableVerticalScrollbar : uiGridConstants.scrollbars.NEVER,
Make sure uiGridConstants is passed into your controller:
angular.module('app').controller('mainController', function($scope, uiGridConstants) { ...
Hope this helps!
I think I solved this problem perfectly after 48 hours,
var app = angular.module('app', ['ngTouch', 'ui.grid', 'ui.grid.pagination', 'ui.grid.autoResize']);
app.controller('MainCtrl', ['$scope', '$http', '$interval', function($scope, $http, $interval) {
var paginationOptions = {
pageNumber: 1,
pageSize: 20,
};
$scope.currentPage = 1;
$scope.pageSize = paginationOptions.pageSize;
$scope.gridOptions = {
rowHeight: 30,
enableSorting: true,
paginationPageSizes: [$scope.pageSize, $scope.pageSize * 2, $scope.pageSize * 3],
paginationPageSize: paginationOptions.pageSize,
columnDefs: [{
name: 'name'
}, {
name: 'gender',
enableSorting: false
}, {
name: 'company',
enableSorting: false
}],
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
gridApi.pagination.on.paginationChanged($scope, function(newPage, pageSize) {
paginationOptions.pageNumber = newPage;
paginationOptions.pageSize = pageSize;
$scope.pageSize = pageSize;
$scope.currentPage = newPage;
$scope.totalPage = Math.ceil($scope.gridOptions.totalItems / $scope.pageSize);
});
}
};
var loadData = function() {
var url = 'https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/100.json';
$http.get(url)
.success(function(data) {
$scope.gridOptions.totalItems = data.length;
$scope.totalPage = Math.ceil($scope.gridOptions.totalItems / $scope.pageSize);
$scope.gridOptions.data = data;
});
};
loadData();
// for resize grid's height
$scope.tableHeight = 'height: 600px';
function getTableHeight(totalPage, currentPage, pageSize, dataLen) {
var rowHeight = 30; // row height
var headerHeight = 50; // header height
var footerHeight = 60; // bottom scroll bar height
var totalH = 0;
if (totalPage > 1) {
// console.log('hehehehe');
if (currentPage < totalPage) {
totalH = pageSize * rowHeight + headerHeight + footerHeight;
} else {
var lastPageSize = dataLen % pageSize;
// console.log(lastPageSize);
if (lastPageSize === 0) {
totalH = pageSize * rowHeight + headerHeight + footerHeight;
} else {
totalH = lastPageSize * rowHeight + headerHeight + footerHeight;
}
}
console.log(totalH);
} else {
totalH = dataLen * rowHeight + headerHeight + footerHeight;
}
return 'height: ' + (totalH) + 'px';
}
$interval(function() {
$scope.tableHeight = getTableHeight($scope.totalPage,
$scope.currentPage, $scope.pageSize,
$scope.gridOptions.data.length);
console.log($scope.tableHeight);
$scope.gridApi.grid.handleWindowResize();
$scope.gridApi.core.refresh();
}, 200);
}]);
.grid {
width: 600px;
}
<!doctype html>
<html ng-app="app">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-touch.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
<script src="http://ui-grid.info/release/ui-grid.js"></script>
<link rel="stylesheet" href="http://ui-grid.info/release/ui-grid.css" type="text/css">
<link rel="stylesheet" href="main.css" type="text/css">
</head>
<body>
<div ng-controller="MainCtrl">
<div ui-grid="gridOptions" ui-grid-pagination id="grid" style="{{tableHeight}}"></div>
<div>
<p>Current Page: {{ currentPage }}</p>
<p>Total Page: {{ totalPage }}</p>
<p>Page Size: {{ pageSize }}</p>
<p>Table Height: {{tableHeight}}</p>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
Also see Plunker: http://plnkr.co/edit/np6y6rgN1ThnT0ZqyJeo?p=preview
$(".gridStyle").css("height","");
remove your height property in your gridstyle class then automatic dynamic height set on your ng-grid..
you can add auto style something like this:
ng-style="{ 'height': myData.length*34 }",and myData is
I find using this piece of code on the stylesheet solved my problem. I disabled the plugin but it works either way.
.ngViewport.ng-scope{
height: auto !important;
overflow-y: hidden;
}
.ngTopPanel.ng-scope, .ngHeaderContainer{
width: auto !important;
}
.ngGrid{
background-color: transparent!important;
}
I hope it helps someone!
In the method where you are trying to store the data for each row within each grid, add a code to calculate the length of the grid in a separate array and push that calculated length to different array. Make sure the index of the grid and index of the array should be same, so that we can access it from the UI together. My approach was as follows:
//Stores the calculated height of each grid.
$scope.gridHeights = [];
//Returns the height of the grid based on the 'id' passed from the UI side.
//Returns the calculated height appended with 'px' to the HTML/UI
$scope.getHeight = function(id){
if($scope.gridHeights[id]) {
return {
'height': $scope.gridHeights[id] + 'px'
};
}else{
return {
'height': '300px'
};
}
};
for (var idx = 0; idx < $scope.auditData.length; idx++) {
//gets the rows for which audit trail/s has to be displayed based on single or multi order.
$scope.gridData[idx] = $scope.auditData[idx].omorderAuditTrailItems;
//Calculates and pushes the height for each grid in Audit Trail tab.
$scope.gridHeights.push(($scope.auditData[idx].omorderAuditTrailItems.length + 2)*30);
//IN HTML, set the height of grid as :
<div id='orderAuditTrailList'>
<div class="row fits-auditTrail" ng-style="getHeight(id)">
<div class="fits-ng-grid" ng-if="auditTrail.omorderAuditTrailItems.length>0" ng-grid="gridOrderAuditTrailList[id]" ng-style="getHeight(id)"></div>
</div>
</div>