Ajax Calls in highchart.js - javascript

Hello there to all developers :-)
I want to ask a question about making Ajax Calls in the highchart.js library
I have some values which I am returning via Ajax based on the information I am giving to the back-end (its an MVC .NET project) and then I want to render a new chart in each div with the class gainChart (I am adding Ids for other purposes,so don't bother them :-) )
var iteratorJs = 0;
$(".gainChart").each(function (i) {
$(this).attr('id', "gainChart" + (i + 1));
var chart = new Highcharts.Chart({
chart: {
renderTo: this,
type: 'line',
margin: 0,
backgroundColor: 'rgba(255,255,255,0.3)'
},
colors: ['#2E5430'],
xAxis: {
lineWidth: 0,
minorGridLineWidth: 0,
lineColor: 'green',
//type: 'datetime',
labels: {
enabled: false
},
categories: [
$.ajax({
type: "POST",
url: "forex-copy-points-days",
data: { page: 0, perPage: 5, iterator: iteratorJs },
dataType: 'json',
async: false,
success: function (data) {
var daysArr = data.days;
JSON.stringify(daysArr);
categories = daysArr;
console.log(daysArr);
}
})
]
},
tooltip: {
formatter: function () {
var text = '';
text = this.y + '$';
return text;
}
},
credits: { enabled: false },
title: { text: null },
legend: {
enabled: false
},
plotOptions: {
series: {
stacking: 'normal',
pointWidth: 10
}
},
series: [{
name: 'Balance',
showInLegend: true,
legendMarkerColor: "green",
legendText: "Profit for account",
data: [
$.ajax({
type: "POST",
url: "forex-copy-points-balance",
data: { page: 0, perPage: 5, iterator: iteratorJs },
dataType: 'json',
async: false,
success: function (balances) {
var balArr = balances.balances;
JSON.stringify(balArr);
data = balArr;
console.log(balArr);
}
})
]
}],
exporting: {
enabled: false
},
responsive: {
rules: [{
condition: {
maxWidth: 600
},
chartOptions: {
legend: {
enabled: false
}
}
}]
}
});
iteratorJs++;
});
The returning data is as it is supposed to be (different strings), yet nothing is displayed - only the background of the chart. Can someone give me a clue how to solve this and what to change in order to solve my problem.
Thanks in advance!

The jQuery $.ajax method call doesn't return the data that results from this call, so you can't write myData = $.ajax(). You have to use the success callback to get the data, and then use it.
So for example, instead of writing this:
categories: [
$.ajax({
type: "POST",
url: "forex-copy-points-days",
data: { page: 0, perPage: 5, iterator: iteratorJs },
dataType: 'json',
async: false,
success: function (data) {
var daysArr = data.days;
JSON.stringify(daysArr);
categories = daysArr;
console.log(daysArr);
}
})
]
You should write something like this:
$.ajax({
type: "POST",
url: "forex-copy-points-days",
data: { page: 0, perPage: 5, iterator: iteratorJs },
dataType: 'json',
async: false,
success: function (data) {
// create graph from AJAX call results
var chart = new Highcharts.Chart({
xAxis: {
categories: JSON.stringify(data.days)
},
series: [{
data: JSON.stringify(balances.balances)
}]
});
}
});

Related

Uncaught TypeError: chart.render is not a function

I'm trying to pass the string value from my controller to my javascript to render my chart thru on click of a button.
In my controller I query the needed data and echo the return value, below is the value
new CanvasJS.Chart("myChart", {
animationEnabled: true,
theme: "light2",
title:{
text: "Devices"
},
axisY: {
title: "From"
},
legend: {
cursor:"pointer",
itemclick : toggleDataSeries
},
toolTip: {
shared: true,
content: toolTipFormatter
},
data: [
{
type: "bar",
showInLegend: true,
name: "A",
dataPoints: [{ y: 2, label: "Keyboard" },{ y: 13, label: "Laptop" }]},{
type: "bar",
showInLegend: true,
name: "B",
dataPoints: [{ y: 1, label: "Keyboard" },{ y: 0, label: "Laptop" }]}
]
})
I used ajax to get the value above like below:
var return_first = function () {
var tmp = null;
$.ajax({
'async': false,
'type': "POST",
'global': false,
'dataType': 'html',
'url': base_url + 'my_controller/dChart',
'data': {
'dev_fil' : $("#dev_fil").val()
},
'success': function (data) {
tmp = data;
}
});
return tmp;
}();
And then I will assign it to a variable and render() it
var chart = return_first;
chart.render();
But it keeps on returning and error Uncaught TypeError: chart.render is not a function
I tried to just render it normally and not from ajax it displays the chart but I need to change the value of the chart when submitting a device name.
Thank you in advance for the help.
---UPDATE---
I tried to pass only the values inside the data[] and call the render() inside the success.
var return_first = function () {
var tmp = null;
$.ajax({
'async': false,
'type': "POST",
'global': false,
'dataType': "html",
'url': base_url + 'my_controller/dChart',
'data': {
'dev_fil' : $("#dev_fil").val()
},
'success': function (data) {
console.log(data)
tmp = new CanvasJS.Chart("myChart", {
animationEnabled: true,
theme: "light2",
title:{
text: "Device Replacement"
},
axisY: {
title: "Outlets"
},
legend: {
cursor:"pointer",
itemclick : toggleDataSeries
},
toolTip: {
shared: true,
content: toolTipFormatter
},
data: [data]
});
tmp.render();
}
});
return tmp;
}();
I'm having an error
Uncaught TypeError: Cannot use 'in' operator to search for 'name' in {
type: "bar",
showInLegend: true,
name: "AA",
dataPoints: [{ y: 13, label: "Laptop" }]}
Its at canvas.minjs
The data comes through as a string, so you are assigning tmp to a string, which does not have the function render(). You need to eval() the string to have it execute the string as code, which would then create your object:
'success': function (data) {
tmp = eval(data);
}
Just a note, eval is generally not the best way to do things. Here you might consider returning just the json settings in your API and creating the object in the success:
var return_first = function () {
var tmp = null;
$.ajax({
'async': false,
'type': "POST",
'global': false,
'dataType': 'json', // notice we changed to 'json' here
'url': base_url + 'my_controller/dChart',
'data': {
'dev_fil' : $("#dev_fil").val()
},
'success': function (data) {
tmp = new CanvasJS.Chart("myChart", data);
}
});
return tmp;
}();
--- UPDATE ---
Based on your most recent code, you want your server side to be returning this:
[
{
type: "bar",
showInLegend: true,
name: "A",
dataPoints: [{ y: 2, label: "Keyboard" },{ y: 13, label: "Laptop" }]},{
type: "bar",
showInLegend: true,
name: "B",
dataPoints: [{ y: 1, label: "Keyboard" },{ y: 0, label: "Laptop" }]}
]
and your client-side code will look like this:
var return_first = function () {
var tmp = null;
$.ajax({
'async': false,
'type': "POST",
'global': false,
'dataType': "json", // note we set json here
'url': base_url + 'my_controller/dChart',
'data': {
'dev_fil' : $("#dev_fil").val()
},
'success': function (data) {
console.log(data)
tmp = new CanvasJS.Chart("myChart", {
animationEnabled: true,
theme: "light2",
title:{
text: "Device Replacement"
},
axisY: {
title: "Outlets"
},
legend: {
cursor:"pointer",
itemclick : toggleDataSeries
},
toolTip: {
shared: true,
content: toolTipFormatter
},
data: data // notice data is not wrapped in brackets because it's already an array
});
tmp.render();
}
});
return tmp;
}();
var chart = return_first;
chart.render();
return_first is your function that is making an ajax call, and you are assigning that to chart. So its normal that javascript is saying: hey, your return_first function doesnt have a function called render.
Maybe you need to assign to another variable your ChartJS var, and then call from there the render. Something like:
var myChart = new CanvasJS.Chart(...);
myChart.render();

Apexcharts remove old data series before render new series

I'm using apex chart for simple data visualization from json output. My charts based on pure javascript and not Vue or other frameworks.
My json (php) backend create two json outputs fro draw the chart as below
JSON 1
{
"x": "2019-05-27 16:18:48",
"y": "100"
},
{
"x": "2019-05-27 16:25:09",
"y": "110"
},
JSON 2
{
"x": "2019-05-27 16:18:48",
"y": "60"
},
{
"x": "2019-05-27 16:25:09",
"y": "65"
},
Based on the above two json outputs I retrieve data and draw my graph using the Category paired values method. below is the code responsible for retrieve data and draw the chart.
function for getting json data
function data_function(){
$.ajax({
type: "Get",
url: backend,
data:{
param: "all_a"
},
async: true,
cache: false,
success: function(data) {
a_data = data;
$.ajax({
apex_task: "Get",
url: backend,
data:{
param: "all_b"
},
async: true,
cache: false,
success: function(data) {
b_data = data;
chart(a_data,b_data);
}
});
}
});
}
function for draw chart
function draw_chart(a_data,b_data) {
var options = {
chart: {
height: 400,
type: 'bar',
stacked: false
},
series: [
{
name: 'a',
data: a_data,
},
{
name: 'b',
data: b_data,
}],
yaxis: [
{
axisTicks: {
show: true,
},
axisBorder: {
show: true,
color: '#008FFB'
},
labels: {
style: {
color: '#008FFB',
}
}
},
]
}
var chart = new ApexCharts(document.querySelector("#chartdiv"), options);
chart.render();
}
This works fine until I second time render the chart with new data. when I load the different data without reloading the windows chart happen to be laggy and render multiple times with the old incorrect data. sometimes I have to run the data_fnction multiple times to render the chart properly.
How can I fix this? Do I need to use function like appendchart ? how can I use wiht my data_function
You should call the render() method just once in the beginning (even with empty array it should work), then call the updateSeries() method in ajax call to update data of the chart.
var options = {
chart: {
height: 400,
type: 'bar',
stacked: false
},
series: [],
yaxis: [{
axisTicks: {
show: true,
},
axisBorder: {
show: true,
color: '#008FFB'
},
labels: {
style: {
color: '#008FFB',
}
}
}]
}
var chart = new ApexCharts(document.querySelector("#chartdiv"), options);
chart.render();
Your ajax call with updateSeries method of the chart
function data_function() {
$.ajax({
type: "Get",
url: backend,
data: {
param: "all_a"
},
async: true,
cache: false,
success: function (data) {
a_data = data;
$.ajax({
apex_task: "Get",
url: backend,
data: {
param: "all_b"
},
async: true,
cache: false,
success: function (data) {
b_data = data;
chart.updateSeries([{
name: 'a',
data: a_data
}, {
name: 'b',
data: b_data
}])
}
});
}
});
}
Docs for updateSeries
Although there is the updateSeries function, you're allowed to render again the values of the chart by destroying the previous ones. This works with ApexCharts, ChartJS, etc.
var options =
{
series: [],
chart:
{
type: 'donut',
height: 150
},
labels: ['...'],
};
// Destroy if exists in order to re-update the data
if (window.myChart)
window.myChart.destroy();
window.myChart = new ApexCharts(chart, options);
window.myChart.render();

high chart total data

I try to populate chart when user click on button .. and chart is display like this
now the problem i want total i.e. as in image in red circle i write TOTAL : 3 .. 3 is beacuse 2 for MV and 1 for DSB so total is 3
I try this
this is the code which i try
<script type="text/javascript">
var strArray = "[['sfdsdfLi', 9],['Kiwsdfi', 3],['Mixesdfd nuts', 1],['Oranges', 6],['Grapes (bunch)', 1]]";
$(function () {
$('#tabledata').on('click', 'tr', function () {
var row = $(this);
var Id = row.find('td')[0].firstChild.data;
var obj = {};
obj.ID = Id;
GetData(obj);
return false;
});
});
function GetData(obj) {
$.ajax({
type: "POST",
url: "WebForm1.aspx/GetVo",
data: JSON.stringify(obj),
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function (result) {
if (result !== null && result.length == 0) {
$("#cont").hide();
return;
}
strArray = result.d;
var myarray = eval(strArray);
$("#cont").show();
$('#cont').highcharts({
chart: {
borderColor: 'Grey',
borderWidth: 2,
type: 'pie',
options3d: {
enabled: true,
alpha: 45
}
},
title: {
text: 'Data1'
},
position: {
align: 'right',
verticalAlign: 'bottom',
x: 10,
y: -10
},
subtitle: {
text: '3D Chart'
},
plotOptions: {
pie: {
innerSize: 100,
depth: 45,
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.y}',
},
showInLegend: true
}
},
series: [{
name: 'Delivered amount',
data: myarray
}]
});
},
error: function (error) {
alert(error);
}
});
}
</script>
now how i get total ? any solutions

How to bind dynamic data to highcharts basic area graph

I have to create the following graph and i have to dynamically load data into it.
Basic Area http://domoticx.com/wp-content/uploads/highcharts-area-basic-standaard.png
Could anyone please help me understanding how can it be done.
Below is where i am able to reach.:
$.ajax({
url: 'EthicsData',
dataType: "json",
type: "GET",
contentType: 'application/json; charset=utf-8',
async: false,
processData: false,
cache: false,
delay: 150,
success: function (data) {
var EthicReg = (data[0].regdet);
var EthicComp = (data[0].compdet);
var EthicsCompletions = new Array();
var EthicsRegistration = new Array();
for (var i in EthicReg) {
var serie = new Array(EthicReg[i].Value, EthicReg[i].year);
EthicsRegistration.push(serie);
}
for (var y in EthicComp) {
var series2 = new Array(EthicComp[y].value,
EthicComp[y].year);
EthicsCompletions.push(series2);
}
DrawEthicsAndCompl(EthicsCompletions, EthicsRegistration)
},
error: function (xhr) {
alert('error');
}
});
};
function DrawEthicsAndCompl(EthicsCompletions, EthicsRegistration) {
debugger;
var chart = new Highcharts.Chart({
chart: {
//plotBackgroundColor: null,
//plotBorderWidth: 1, //null,
//plotShadow: false,
renderTo: 'container1',
type: 'area'
},
title: {
text: 'US and USSR nuclear stockpiles'
},
subtitle: {
text: 'something'
},
xAxis: {
allowDecimals: false,
labels: {
formatter: function () {
return 10; // clean, unformatted number for year
}
}
},
yAxis: {
title: {
text: 'Nuclear weapon states'
},
labels: {
formatter: function () {
return this.value;
}
}
},
tooltip: {
pointFormat: '{series.name} produced <b>{point.y:,.0f}</b><br/>warheads in {point.x}'
},
plotOptions: {
area: {
pointStart: 2010,
marker: {
enabled: false,
symbol: 'circle',
radius: 2,
states: {
hover: {
enabled: true
}
}
}
}
},
series: [{
name: 'Registration',
data: [EthicsRegistration[0]]
}, {
name: 'Completions',
data: [EthicsCompletions[0]]
}]
});
}
Here is the link which demo's same but static data:
(http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/area-basic/)
Just change the order in which you are pushing items in array , means
Instead
var serie = new Array(EthicReg[i].Value, EthicReg[i].year);
EthicsRegistration.push(serie);
Use
var serie = new Array(EthicReg[i].year, EthicReg[i].Value);
EthicsRegistration.push(serie);
Also , If you are getting year's value don't use pointStart: 2010 instead leave it on the data you are getting from the response above.
Thanks #Nishith for providing the right direction. I modified the code as below:
name: 'Registration',
data: [EthicsRegistration[0][1], EthicsRegistration[1][1], EthicsRegistration[2][1]]
}, {
name: 'Completions',
data: [EthicsCompletions[0][1],EthicsCompletions[1][1],EthicsCompletions[2][1]]
}]
});

Highcharts ajax load

I have a problem using Highcharts.
I want to get an array from my php API and treat the results as my datapoints.
Here is the code :
$(function () {
$(document).ready(function () {
Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
$('#graph_temperature').highcharts({
chart: {
zoomType: 'x',
type: 'area'
},
credits: {
enabled: false
},
title: {
text: 'Temperature'
},
legend: {
enabled: false
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'Temperature',
color: '#ff851b',
marker: {
enabled: false
},
data: (function () {
var data_graph;
$.ajax({
url: "https://urlhidden.com/ajaxsql.php?f=get_all_temperature",
type: "GET",
async: false,
success: function (data) {
data_graph = [].concat(data);
$("#debug").html(data_graph);
}
});
return data_graph;
})()
}]
})
})
});
My array is like :
[[1394908920000,20.87], [1394908980000,20.87], [1394909040000,20.87], [1394909100000,20.87], [1394909160000,20.87], [1394909220000,20.87],...]
My problem is that Highchart doesnt draw my chart. Axis, title are OK but my area is missing.
In order to debug i used this line :
$("#debug").html(data_graph);
And the array is well formed as i can see in my "debug" div.
When i put manually the entire array :
data:[[1394908920000,20.87], [1394908980000,20.87], [1394909040000,20.87], [1394909100000,20.87], [1394909160000,20.87], [1394909220000,20.87],...],
it works well.
Anybody have an idea to help me ?
I haven't test my code but it should work.I hope you'll understand my idea.
$(function () {
$(document).ready(function () {
Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
params = {
chart: {
zoomType: 'x',
type: 'area'
},
credits: {
enabled: false
},
title: {
text: 'Temperature'
},
legend: {
enabled: false
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'Temperature',
color: '#ff851b',
marker: {
enabled: false
}
}]
};
$.ajax({
url: "https://urlhidden.com/ajaxsql.php?f=get_all_temperature",
type: "GET",
async: false,
context:document.body,
success: function (data) {
//data should be converted to json object using [..]
//remove data variable in this format you should get the data
data = [[1394908920000,20.87], [1394908980000,20.87], [1394909040000,20.87]];
params.series[0].data = data;
$('#graph_temperature').highcharts(params);
}
});
})
});
Updated

Categories

Resources