Am Chart does not load chart after ajax call - angularjs

I fetch data from API by making ajax call then pass this data to the chart.
I am not able to render the chart. Can anyone suggest me what may be the issue?
This is my ajax call
You can see after ajax call i am trying to push to scope variable and trying to add to chart.
for reference please find in this link http://jsfiddle.net/w3vpc35o/41/
angular.module('amChartsDirectiveExample', ['amChartsDirective']).controller('amChartsController', function ($scope) {
$scope.call = function(){
$http({
method: "get",
global: false,
async: true,
url: "server/test.php
}).
success(function(data) {
/*Assume data like like [{
year: 2005,
income: 23.5,
expenses: 18.1
}, {
year: 2006,
income: 26.2,
expenses: 22.8
}, {
year: 2007,
income: 30.1,
expenses: 23.9
}, {
year: 2008,
income: 29.5,
expenses: 25.1
}, {
year: 2009,
income: 24.6,
expenses: 25
}]*/
$scope.rest = data
$scope.amChartOptions = {
data:$scope.res ,
type: "serial",
theme: 'black',
categoryField: "year",
rotate: true,
pathToImages: 'https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.13.0/images/',
legend: {
enabled: true
},
chartScrollbar: {
enabled: true,
},
categoryAxis: {
gridPosition: "start",
parseDates: false
},
valueAxes: [{
position: "top",
title: "Million USD"
}],
graphs: [{
type: "column",
title: "Income",
valueField: "income",
fillAlphas: 1,
}]
}
});
}
$scope.call();
});

You didn't mentioned if you use some angular wrapper for amCharts or not, but if not, maybe you called var chart = AmCharts.makeChart(...) before the ajax call completed and you forgot to call chart.validateData(); after?
Will greatly help if you will post here some full code related to this issue
EDIT
It's seems that you use GrantMStevens/amCharts-Angular.
Use the technique mentioned in the documentation: 'Promise based chart rendering' to resolve the data in async: http://jsfiddle.net/w3vpc35o/83/
In general, what you need to do is to create the ChartOptions like this:
this.amChartOptions = $timeout(function(){
return {
data: this.dataFromPromise(),
type: "serial",
...
}.bind(this), 1000)
and fetch the data in async using something like this:
this.dataFromPromise = function(){
var deferred = $q.defer();
$http({
method : "GET",
url : "/server/endpoint"
}).then(function mySucces(response) {
deferred.resolve(response);
});
return deferred.promise;
};

Related

Highcharts graph does not update with firebase

$scope.hhData = $firebaseArray(aRef.orderByChild('ts').startAt('2018-07-02').limitToLast(50));
$scope.hhData.$loaded().then(function () {
$scope.chartSeriesYArray = [];
$scope.chartSeriesXArray = [];
$scope.hhData.$watch(function() {
angular.forEach($scope.hhData, function (value) {
$scope.chartSeriesXArray.push(moment(value.ts).format('MMMM Do YYYY, h:mm:ss'));
$scope.chartSeriesYArray.push(parseFloat(value.ein));
});
Highcharts.chart('chart', {
chart: {
type: 'column'
},
title: {
text: 'Half Hourly Energy Consumption'
},
xAxis: {
categories: $scope.chartSeriesXArray,
crosshair: true
},
yAxis: {
min: 0,
title: {
text: 'Energy (kwh)'
}
},
series: [{
name: 'Meter01',
data: $scope.chartSeriesYArray
}]
});
});
});
I wanted to be able to update the data live from Firebase into the chart. However, this code only allows the data to be updated once at the start and it never updates itself again. Is there any way to work around this? - tried the $interval method as suggested but it didn't work :(
Update: I managed to do so with $watch. However, this now means that my graph will only show when there is data coming in. If there is no data coming in (EG: when you just turn on the system) then no graph will show at all. This there another way around this
Try using the $interval service to retrieve your data after a certain amount of time.
$interval(function() {
$scope.hhData.$loaded().then(function () {
$scope.chartSeriesYArray = [];
$scope.chartSeriesXArray = [];
angular.forEach($scope.hhData, function (value) {
$scope.chartSeriesXArray.push(moment(value.ts).format('MMMM Do YYYY, h:mm:ss'));
$scope.chartSeriesYArray.push(parseFloat(value.ein));
});
Highcharts.chart('chart', {
chart: {
type: 'column'
},
title: {
text: 'Half Hourly Energy Consumption'
},
xAxis: {
categories: $scope.chartSeriesXArray,
crosshair: true
},
yAxis: {
min: 0,
title: {
text: 'Energy (kwh)'
}
},
series: [{
name: 'Meter01',
data: $scope.chartSeriesYArray
}]
});
});
}, 5000); //this function will run every 5 seconds
*don't forget you also need to add the $interval parameter to your controller, and the interval goes by milliseconds
app.controller('myCtrl',["$scope", "$interval", function($scope, $interval) {
//code goes here
}]);

Angular chart: can't send the data to the chart

I'm trying to build a chart with angular
my problem is to send the data received by the API to the chart
The json i receive is like this:
{"2016":"8441,7728,10600,7297,8939,8622,5142,4718,8782,7325,7325,5222","2017":"7491,6245,7723,4701,6439,6111,7496,3724,7502,2839"}
i do:
$http({
method: 'POST',
data : {famille: selectedFamille.Id, societe: $scope.societe},
url: '/api/EBP/get_the_ca.php',
dataType : "json",
}).then(function (response) {
// on success, we send the information to the chart
$scope.labels = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juilley", "Août", "Sept.", "Oct.", "Nov.", "Déc."];
$scope.series = ['CA 2016', 'CA 2017'];
$scope.datasetOverride = [{
yAxisID: 'y-axis-1'
}, {
yAxisID: 'y-axis-2'
}];
$scope.options = {
legend: {
display: true
},
scales: {
yAxes: [{
id: 'y-axis-1',
type: 'linear',
display: true,
position: 'left',
ticks: {min: 0, max:100000}
}]
}
};
$scope.data = [
[response.data['2016']],
[response.data['2017']]
];
everything works fine if between response.data['2016'] and response.data['2017'] i put the content of those vars

KendoUI Grid for AngularJS binding error from asp.net mvc controller. Success is not a function error

I attempt to do simple task using KendoUI grid for AngularJS in asp.new mvc application. It is binding data to grid from mvc controller.
asp.net mvc controller method:
public ActionResult GetCdcReport()
{
var testJson =
#"{ProductID:'1',ProductName:'Chai',UnitPrice:'18',UnitsInStock:'39',Discontinued:'false'}";
var json = JObject.Parse(testJson);
return new JSONNetResult(json);
}
angularjs service function:
function getImportResultReport() {
return httpPost('getCdcReport');
}
code from component for data binding:
$scope.mainGridOptions = {
columns: [
{ field: "ProductID", title: "ID" },
{ field: "ProductName", title: "Product Name" },
{ command: [{ template: "<button class='k-button' ng-click='showDetails(dataItem)'>Show details</button>" }] },
],
pageable: true,
dataSource: {
pageSize: 5,
transport: {
read: function (e) {
dataservice.getImportResultReport().
success(function (data) {
e.success(data);
}).
error(function (data, status) {
alert('something went wrong');
console.log(status);
});
}
}
}
};
I see that server method is called but in console i get following client error:
dataservice.getImportResultReport(...).success is not a function
In similar question i read that:
The $http legacy promise methods success and error have been
deprecated. Use the standard then method instead.
i replace binding code on:
$scope.mainGridOptions = {
columns: [
{ field: "ProductID", title: "ID" },
{ field: "ProductName", title: "Product Name" },
{ command: [{ template: "<button class='k-button' ng-click='showDetails(dataItem)'>Show details</button>" }] },
],
pageable: true,
dataSource: {
pageSize: 5,
transport: {
read: function (e) {
dataservice.getImportResultReport().
then(function (data) {
return data;
});
}
}
}
};
After that I don't receive this error but grid stay without data.
Also i attempted do it like:
vm.mainGridOptions = {
columns: [
{ field: "ProductID", title: "ID" },
{ field: "ProductName", title: "Product Name" },
{ command: [{ template: "<button class='k-button' ng-click='showDetails(dataItem)'>Show details</button>" }] },
],
pageable: true
};
$scope.mainGridOptions.DataSource = dataservice.getImportResultReport();
it is also not work.
What i'm doing wrong?
It is example from telerik site. If in binding logic replase dataservice.getImportResultReport() on $http.jsonp('URL FROM EXAMPLE') then it is work.

How to share code in angular js (concept of code resuability in angular js?

i am new to angular js and i want to share and make certain codes reusable. i have tried to do that using services and factory. But i am getting error.
'use strict';
angular.module('myApp.ctrls')
.controller('Ctrl_HubStockOnHandMode', function($http, $scope, reportService) {
$scope.HubStockOnHandModeGridOptions = {
dataSource: {
type: "jsonp",
transport: {
read: function(e) {
reportService.WebAPI('abc/BIUMo', {
EnvironmentCode:'JMVH',
OrderBy: getOrderBy(e.data.sort)
}).then(function (d) {
$scope.data = d;
e.success(d.Data);
});
}
},
serverPaging: true,
serverSorting: true
},
height:config.GridHeight,
scrollable:true,
sortable: {
mode: "single",
allowUnsort: true
},
filterable: {
extra: false,
operators: {
string: {
startswith: "Starts with",
eq: "Is equal to",
neq: "Is not equal to",
contains: "Contains"
}
}
},
pageable: false,
columns: [
{
field: "RowNumber"
,title: "No."
,width: "50px"
,sortable:false
,filterable: false
},
{
field: 'ItemCTSH'
,title:'Item'
,template: "<div kendo-tooltip title='#= ItemCT #' > #= ItemCTSH # </div>"
,filterable: {
ui: itemFilter
}
},
]
};
}
//Get Item List
$http.get('http://webapi.dashboard.hcmisonline.org/api/OID_WebApi/IssuedItemList')
.success(function (data) {
$scope.items = data.Data;
});
function itemFilter(element) {
element.kendoAutoComplete({
dataSource: $scope.items
});
}
}
});
I want to reuse the functions like the Get item. i have other pages/grids that use exactly this code, except changing the environment code
how to i solve this issue?
thanks

Kendo Scheduler Dynamic DataSource with Angular

I have a Kendo Scheduler on my page.
<div kendo-scheduler k-options="schedulerOptions" k-data-source="items"></div>
My angular controller will make a call to the server to get data, it looks like this, but I do not know what my URL parameter will be until it loads up ($scope.$watch).
$scope.$watch(function () { return MyService.leadID; }, function (newValue) {
if (newValue) {
getAppointmentsTabData(newValue);
}
});
var getAppointmentsTabData = function (leadID) {
MyService.getAppointmentsTabData(leadID)
.then(function (data) {
$scope.items = data;
}
}
);
};
How can I bind this data to my Kendo Scheduler?
I can get this Scheduler to work with static data, but not the JSON list of objects that get returned when the server sends them. I would like to be able to bind my $scope.items to the dataSource, but that does not appear to work.
Here is the schedulerOptions code.
$scope.schedulerOptions = {
date: new Date("2014/10/13"),
startTime: new Date("2014/10/13 07:00 AM"),
height: 310,
views: [
"agenda",
{ type: "week", selected: true, allDaySlot: false },
{ selectedDateFormat: "{0:dd-MM-yyyy}" }
],
eventTemplate: "<span class='custom-event'>{{dataItem.title}}</span>",
allDayEventTemplate: "<div class='custom-all-day-event'>{{dataItem.title}}</div>",
timezone: "Etc/UTC",
dataSource: {
data: $scope.items,
schema: {
model: {
id: "id",
fields: {
id: { from: "ID", type: "number" },
appointmentId: { from: "AppointmentId", type: "number" },
resource: { from: "Resource", type: "number" },
description: { from: "Description" },
isAllDay: { type: "boolean", from: "IsAllDay" },
end: { from: "End", type: "date" },
start: { from: "Start", type: "date" },
title: { from: "Title", defaultValue: "No title" },
startTimezone: { from: "StartTimezone" },
endTimezone: { from: "EndTimezone" },
recurrenceRule: { from: "RecurrenceRule" },
recurrenceException: { from: "RecurrenceException" },
}
}
},
}
};
I can get the static approach to work. I cannot really use the remote data approach that looks like this (below) because I do not know what my URL is until my $scope.$watch is triggered. I need to append query string params.
dataSource: {
batch: true,
transport: {
read: {
url: "/MyController/GetMyData",
dataType: "json",
},
Does anyone have any suggestions on how I can populate my Scheduler dataSource dynamically?
I have seen this question, Kendo update scheduler options dynamically, but I am not having any luck getting the setOptions(). If only I could call $scope.myScheduler.setOptions("dataSource", myJsonObjectArry), that would be awesome, but nothing.
I am able to manipulate $scope.myScheduler._data (as an array), but I need some form of a refresh method to redraw my UI. This approach doesn't seem right though.
Thanks for any help.
I am answering my own question. In case you run into this situation, here is how I solved it.
Here is my schedulerOptions now. Notice there is no dataSource set and no schema. This is because I will populate that with my own dataSource dynamically.
$scope.schedulerOptions = {
date: new Date("2014/10/13"),
startTime: new Date("2014/10/13 07:00 AM"),
showWorkHours: true,
height: 310,
views: [
"agenda",
{ type: "week", selected: true, allDaySlot: false },
{ selectedDateFormat: "{0:dd-MM-yyyy}" }
],
edit: $scope.edit,
editable: {
template: $("#editor").html()
},
timezone: "Etc/UTC",
dataSource: {
data: [], // will be set dynamically
}
};
When my data is returned to this js controller, I will call this.
$scope.myScheduler.dataSource.data(getSchedulerEvents($scope.data.items));
Which in turn will call this, which creates the dataSource for me.
var getSchedulerEvents = function (items) {
var result = [];
var event;
for (var i = 0, length = items.length; i < length; i++) {
event = items[i];
result.push(new kendo.data.SchedulerEvent({
id: event.ID,
title: event.Title,
description: event.Description,
start: kendo.parseDate(event.Start),
end: kendo.parseDate(event.End),
isAllDay: event.IsAllDay,
recurrenceException: event.RecurrenceException,
recurrenceId: event.RecurrenceId,
recurrenceRule: event.RecurrenceRule,
resource: event.Resource,
}));
}
return result;
}
If you run into this problem, hopefully this helps.

Resources