Display data in bar chart using angular-chart - angularjs

I am trying to display data on a bar chart using angular-chart. I am trying retrieving the data from a database. I want to display all data on the chart for the last five (5) years including this year and also get the data to correspond with the years. So far I am only using 2 yrs, as shown below.
Json Array
Angularjs
app.controller('ChartCtrl', ['$scope', '$http', function ($scope, $http) {
var currentYear = new Date().getFullYear();
var allYrs = [];
// get data from database
$http.get('/dashboard/incident').success(function(incidents) {
$scope.incidentCnt = incidents;
console.log($scope.incidentCnt);
for (var i = 0; $scope.incidentCnt.length; i++) {
// Gets the current year and last 4 years (5 yrs total)
for(var year = currentYear; year >= currentYear-4; year--) {
allYrs.push(year);
$scope.labels = allYrs; // display years
$scope.series = [
'Aggravated Assault',
'Arson',
'Burglary',
'Forcible Sex Offense',
'Hate Crime',
'Motor Vehicle Theft',
'Murder or Non-Negligent Manslaughter',
'Negligent Manslaughter',
'Non-Forcible Sex Offense',
'Relationship/Dating Violence',
'Robbery',
'Stalking'
];
$scope.data = [
[
$scope.incidentCnt[i].assault,
$scope.incidentCnt[i].arson,
$scope.incidentCnt[i].burglary,
$scope.incidentCnt[i].fSexOffense,
$scope.incidentCnt[i].hateCrime,
$scope.incidentCnt[i].vehicleTheft,
$scope.incidentCnt[i].nonNegligentMaslaughter,
$scope.incidentCnt[i].negligentMaslaughter,
$scope.incidentCnt[i].nonForcibleSexOffense,
$scope.incidentCnt[i].rshipDatingViolence,
$scope.incidentCnt[i].robbery,
$scope.incidentCnt[i].stalking
]
];
}
};
});
}]);
Chart's current look
Any help would be much appreciated. Thank you...

I would simply create a custom filter to show last 5 years data
Filter
app.filter('for5Years', function(){
return function(values){
var returnValues = [],
date = new Date(),
currentYear = date.getFullYear(),
limitYear = currentYear - 4;
angular.forEach(values, function(value, index){
if(value.incidentyear <= currentYear && value.incidentyear >= limitYear){
returnValues.push(value);
}
});
return returnValues;
}
});
Controller
app.controller('ChartCtrl', ['$scope', '$http', '$filter', function($scope, $http, $filter) {
var currentYear = new Date().getFullYear();
var allYrs = [];
// get data from database
$http.get('/dashboard/incident').success(function(incidents) {
$scope.incidentCnt = $filter('for5Years')(incidents); //this line will do filtering for you.
console.log($scope.incidentCnt);
//$scope.labels = allYrs; // display years logic to do
for (var i = 0; $scope.incidentCnt.length; i++) {
$scope.series = [
'Aggravated Assault',
'Arson',
'Burglary',
'Forcible Sex Offense',
'Hate Crime',
'Motor Vehicle Theft',
'Murder or Non-Negligent Manslaughter',
'Negligent Manslaughter',
'Non-Forcible Sex Offense',
'Relationship/Dating Violence',
'Robbery',
'Stalking'
];
$scope.data = [
[
$scope.incidentCnt[i].assault,
$scope.incidentCnt[i].arson,
$scope.incidentCnt[i].burglary,
$scope.incidentCnt[i].fSexOffense,
$scope.incidentCnt[i].hateCrime,
$scope.incidentCnt[i].vehicleTheft,
$scope.incidentCnt[i].nonNegligentMaslaughter,
$scope.incidentCnt[i].negligentMaslaughter,
$scope.incidentCnt[i].nonForcibleSexOffense,
$scope.incidentCnt[i].rshipDatingViolence,
$scope.incidentCnt[i].robbery,
$scope.incidentCnt[i].stalking
]
];
}
});
}]);

Related

Angular - Get days Of Week for weather info

I want to get days of the week from data weather Json , I am using this code
'
var dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
var date = new Date();
$scope.wDay = dayNames[date.getDay()];
html
{{wDay}}
get result only one day 'sun' not all days of week
full json data
{
"daily": {
"summary": "لا أمطار خلال الأسبوع مع درجات حرارة ترتفع حتى 50°C يوم الأربعاء",
"icon": "clear-day",
"data": [
{
"time": 1469912400,
"summary": "اجواء جافة خلال اليوم",
"icon": "clear-day",
"sunriseTime": 1469931375,
"sunsetTime": 1469981058,
"moonPhase": 0.91,
"precipIntensity": 0,
"precipIntensityMax": 0,
"precipProbability": 0,
"temperatureMin": 30.7,
"temperatureMinTime": 1469930400,
},
This program is time dependent.
new Date().getDay()
wil always retuen you 0 today
You will only see Sunday - as it's what you specifically test for it with:
dayNames[date.getDay()]; - number corresponding to the day of the week for the given date.
If you want them all, simply ng-repeat dayNames:
var dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
var date = new Date();
function MyCtrl($scope) {
$scope.today = dayNames[date.getDay()];
$scope.all = dayNames;
}
Today is {{today}}!
<div ng-repeat="day in all">
{{day}}
</div>
http://jsfiddle.net/Lvc0u55v/7751/
Edit:
change in the scope of the question, so here's an addition to the answer. It can of course be written in a more condensed manner, but expanded for brevity:
http://jsfiddle.net/Lvc0u55v/7896/
I added MomentJS (http://momentjs.com) - great for working with dates.
//Added a filter to grab today's data from JSON
myApp.filter('GetToday',function(){
return function(epoch) {
//Get today
var today = moment();
//Loop through all the daily nodes from the JSON
for (var i = 0; i < epoch.length; i++) {
//convert UNIX timestamp to date
var json = moment.unix(epoch[i].time);
//determine difference between dates
var duration = moment.duration(json.diff(today));
//convert the difference into hours
var hours = duration.asHours();
//if it's more than 0 and less than 24 (today) return this node
if(hours > 0 && hours < 24) {
return epoch[i];
}
}
}
});
myApp.controller('MyCtrl', ['$scope', '$filter', function($scope, $filter){
$scope.daily = $filter('GetToday')(data[0].daily.data);
}]);

rendering html from a controller in angular

Hopefully someone can point my in the right direction.
I am building a web app and part of it requires a user to click a button as fast as they can to obtain a score. The design dictates that I will need to show this score in double digits i.e 9 would be 09 so for styling I need to wrap span tags around each digit.
I have got everything working as required, I'm just having an issue with outputting the score that is wrapped in span tags as rendered html in my view.
I've put together a fiddle for the section that is causing me problems. Any advice, help, best practices etc is much appreciated.
What I've tried:
I've included a few of the things I've tried. Basically they involve using $sce and trying to ng-bind-html in the view. Attempt 3 seems the most logical to me but the $scope.count isn't being updated. I'm guessing I need to add a $watch or $apply function to keep it binded? but I'm not too sure how to implement it or even if this is good practice. Also, because I'm outputting html is it better practice to do this in a directive?
Fiddle http://jsfiddle.net/funkycamel/gvxpnvqp/4/
HTML
<section ng-app="myApp">
<div ng-controller="MyController">
<button ng-click="add(1)">add</button>
<!-- First attempt -->
<p class="first-attempt">{{ pad(count) }}</p>
<!-- Second attempt -->
<!-- in order for this attempt to work I have to call the pad2 function which
returns trustedHtml -->
{{ pad2(count) }}
<p class="second-attempt" ng-bind-html="trustedHtml"></p>
<!-- Third attempt -->
<p class="third-attempt" ng-bind-html="moreTrustedHtml"></p>
</div>
Javascript
var app = angular.module('myApp', []);
app.controller('MyController', ['$scope', '$sce', function ($scope, $sce) {
// Set initial count to 0
$scope.count = 0;
// function to add to $scope.count
$scope.add = function (amount) {
$scope.count += amount;
};
// Attempt 1
// make sure number displays as a double digit if
// under 10. convert to string to add span tags
$scope.pad = function (number) {
var input = (number < 10 ? '0' : '') + number;
var n = input.toString();
var j = n.split('');
var newText = '';
var trustedHtml = '';
for (var i = 0; i < n.length; i++) {
newText += '<span>' + n[i] + '</span>';
}
return newText;
};
// Attempt 2 - trying to sanitise output
// same as above just returning trusted html
$scope.pad2 = function (number) {
var input = (number < 10 ? '0' : '') + number;
var n = input.toString();
var j = n.split('');
var newText = '';
var trustedHtml = '';
for (var i = 0; i < n.length; i++) {
newText += '<span>' + n[i] + '</span>';
}
// return sanitised text, hopefully
$scope.trustedHtml = $sce.trustAsHtml(newText);
return $scope.trustedHtml;
};
// Attempt 3
// Trying to sanitise the count variable
$scope.moreTrustedHtml = $sce.trustAsHtml($scope.pad($scope.count));
}]);
These currently output
<span>0</span><span>0</span>
<span>0</span><span>0</span>
00
00
Again any advice/help is greatly appreciated.
Far simpler solution:
HTML
<p>{{ count < 10 ? '0' + count : count}}</p>
Controller:
app.controller('MyController', ['$scope', function ($scope) {
$scope.count = 0;
$scope.add = function (amount) {
$scope.count += amount;
};
}]);
DEMO
If you prefer you can do the padding in the controller instead, just use another variable
app.controller('MyController', ['$scope', function ($scope) {
var count = 0;
$scope.countText = '0';
$scope.add = function (amount) {
count += amount;
$scope.countText = count < 10 ? '0' + count : count;
};
}]);

display array conditionally : Angular

I'm trying to filter my array : here is my fiddle : Demo.
there are two select list , here is the condition :
when top select list === 123 ====> bottom select list should show 001,002,003
and
when top select list === 1234 ====> bottom select list should show 002,004,005
should i use something like this .slice(1, 3) ?
Many Thanks
Here is a fiddle that does what you want, where 1234 shows 002,004,005 just because it does. here
var app = angular.module('myApp', []);
app.controller('mainCtrl', function($scope){
$scope.colors = [
{name:'black', shade:'123'},
{name:'white', shade:'1234'},
];
var allRanges = [
{id:'001', number:'1'},
{id:'002', number:'2'},
{id:'003', number:'3'},
{id:'004', number:'4'},
{id:'005', number:'5'}
];
$scope.range = [];
$scope.check = function(){
var filter;
if($scope.color === "black"){
filter = function(r){
if(r.number < 4){
return true;
}
};
} else if($scope.color === 'white'){
filter = function(r){
if(['2','4','5'].indexOf(r.number) >= 0){
return true;
}
};
}
$scope.range = allRanges.filter(filter);
}
});

Getting an 'Error: [$injector:unpr] Unknown provider: ' error

I'm trying to creata a dynamic drop down select menu. I'm getting an unknown provider error relating to a function I'm using to create a date range. Here is my code:
HTML
<ul data-role="listview" data-inset="true" >
<li>
<select id="makeSuperCategory" data-role="listview" ng-options="catagory as catagory.text for catagory in catagories.cast " ng-model="itemsuper" ng-change="changeData()">
</select>
</li>
</ul>
<ul data-role="listview" data-inset="true">
<li>
<select data-role="listview" ng-options="type as type.text for type in types.cast " ng-model="item1" ng-change="update()">
</select>
</li>
</ul>
Factories
var myApp = angular.module('myApp',[]);
myApp.factory('catagories',function(){
var makes = {};
makes.cast = [
{
value: "acura",
text: "Acura"
},
{
value: "audi",
text: "Audi"
},
{
value: "geo",
text: "Geo"
},
{
value: "hummer",
text: "Hummer"
},
];
return makes;
});
myApp.factory('acura',function( production_range,makesProductionEnded, makesInProduction){
var endedProductionObject = makesProductionEnded.filter(function( obj) {
return obj.make === this;
});
$scope.acura ={};
$scope.start = 1986 <!-- date Honda began production of the Acura product line -->
<!-- Set the most recent year option if still in production according to current month and model year change over October -->
$scope.setEnd = function(){
if($inArray(this, makesInProduction) > 0){
if(new Date().getMonth() < 10){
end = new Date().getFullYear();
} else {
end = new Date().getFullYear() + 1;
}
<!-- Set most recent year option if no longer in production according to year property value of object that matches this make in the endedProductionObject array -->
} else {
end = endedProductionObject.year;
}
return end;
}
$scope.acura.cast = [];
angular.foreach(years, function(value, year){
acura.cast.push(acura[year] = value);
});
return acura;
});
myApp.factory('audi',function(){
var audi = {};
audi.cast = [
<!--This will follow a similar pattern as acura once that is resolved -->
];
return audi;
});
myApp.factory('geo',function(){
var geo = {};
geo.cast = [
<!--This will follow a similar pattern as acura once that is resolved -->
];
return geo;
});
myApp.factory('hummer',function(){
var hummer = {};
hummer.cast = [
<!--This will follow a similar pattern as acura once that is resolved -->
];
return hummer;
});
Controller
myApp.controller('makeTypeCtrl',function($scope, acura, audi, geo,hummer, setNulls, catagories, production_range){
<!-- Push the model years into the years array according to the start and end dates -->
$scope.production_range = function(start, end){
var years = [];
for(var year = start; year <= end; year++){
years.push(year);
}
return years;
}
<!-- Defines the makes no longer in production and the date production ended for that make -->
$scope.makesProductionEnded = [{make:'eagle', year:1999}, {make:'geo', year:1997}]
<!-- Defines makes still in production -->
$scope.makesInProduction = ['acura', 'audi'];
$scope.catagories = catagories;
$scope.types = setNulls;
$scope.changeData = function() {
if($scope.itemsuper.text == "Acura") {
$scope.types = acura;
} else if($scope.itemsuper.text == "Audi") {
$scope.types = audi;
} else if($scope.itemsuper.text == "Geo") {
$scope.types = geo;
} else if($scope.itemsuper.text == "Hummer") {
$scope.types = hummer;
} else {
$scope.types = setNulls;
}
}
});
Here is a link to a jsFiddle
The issue is that you are trying to inject production_range into your acura factory. But production_range is a variable on a controller's scope, not a factory or service that can be injected.
The second parameter to a factory should be a function that takes dependencies as its parameters. By dependencies I mean factories / services or anything else thats created from a provider, see https://docs.angularjs.org/guide/services and https://docs.angularjs.org/guide/providers.
Read this as well: https://docs.angularjs.org/guide/di

Convert birthday to age in angularjs

I want to display age of all my users to grid. I am reading data from facebook.I am not storing it at anywhere.
i am displaying date like :
{{ friend.birthday }}
How can i display age instead of displaying birthday.
if it is possible to create filters than how to create filter and how to apply it.
You can implement a function:
Controller:
$scope.calculateAge = function calculateAge(birthday) { // birthday is a date
var ageDifMs = Date.now() - birthday.getTime();
var ageDate = new Date(ageDifMs); // miliseconds from epoch
return Math.abs(ageDate.getUTCFullYear() - 1970);
}
HTML
{{ calculateAge(friend.birthday) }}
Or a filter:
app.filter('ageFilter', function() {
function calculateAge(birthday) { // birthday is a date
var ageDifMs = Date.now() - birthday.getTime();
var ageDate = new Date(ageDifMs); // miliseconds from epoch
return Math.abs(ageDate.getUTCFullYear() - 1970);
}
return function(birthdate) {
return calculateAge(birthdate);
};
});
HTML
{{ friend.birthday | ageFilter }}
Age algorithm taken from this SO answer.
[EDIT] If the age is less than 1 year, and you want to show months, you can modify the ageFilter to calculate the month difference:
app.filter('ageFilter', function() {
function calculateAge(birthday) { // birthday is a date
var ageDifMs = Date.now() - birthday.getTime();
var ageDate = new Date(ageDifMs); // miliseconds from epoch
return Math.abs(ageDate.getUTCFullYear() - 1970);
}
function monthDiff(d1, d2) {
if (d1 < d2){
var months = d2.getMonth() - d1.getMonth();
return months <= 0 ? 0 : months;
}
return 0;
}
return function(birthdate) {
var age = calculateAge(birthdate);
if (age == 0)
return monthDiff(birthdate, new Date()) + ' months';
return age;
};
});
Demo Plunker - Age Function
Demo Plunker - Age Filter
Demo Plunker - Age Filter with Months < 1 year
If you're value is just for example "05/01/2016". This will be a useful code to convert the date to birthday.
AngularJS
app.filter('ageFilter', function(){
return function(birthday){
var birthday = new Date(birthday);
var today = new Date();
var age = ((today - birthday) / (31557600000));
var age = Math.floor( age );
return age;
}
});
HTML
{{ relationTypePreDefined.birthdate | ageFilter }}
By the way I used this solution to convert a date coming from a jquery datepicker input to age.
If you are using momentjs. Then you can create filter simply by using this snippet
var now = "04/09/2013 15:00:00";
var then = "04/09/2013 14:20:30";
moment.utc(moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"))).format("HH:mm:ss")
Idk why I can never reply to people, says I need more rep but to rep I need to comment.. whatever.
In response to #Dean Christian Armada's, I kept getting an error regarding the filter. But changing to the following seems to work fine so I do appreciate it!
$scope.getAge = function(birthday){
var birthday = new Date(birthday);
var today = new Date();
var age = ((today - birthday) / (31557600000));
var age = Math.floor( age );
return age;
}
And for the HMTL
{{ getAge(birthdate) }}

Resources