Inside a function via ajax I created Highcharts that draws some line charts (3 charts). I'm trying to save all chart.series in a global variable. when the function runs for first time and I print the variable everything is ok, but after that I run the function for second time, the variable displays nothing.
index.html
.
.
.
var seriesSelectedList;
var seriesEdited;
function Change_Series_Style(){
$.ajax({
method: "GET",
data: {...},
url: '{% url '...' %}',
dataType: 'json',
success: function (context) {
if (seriesSelectedList.length > 0) {
.
.
.
chart = Highcharts.chart({
chart: {...},
title: {...},
yAxis: {...},
xAxis: {...},
tooltip: {...},
plotOptions: {...},
series: context.main_data_list,
responsive: {...}
});
seriesEdited = chart.series
console.log(seriesEdited)
}else{
.
.
.
console.log(seriesEdited)
}
}
}
}
for first time the if condition is true and the output log is the following:
and for second time the condition is not true and else block should be execute. the output is the following:
In second time why do not have same series in the variable? and how can I save all series in a variable and use it again? Thanks in advance.
Related
Actually i want to redraw the HighChart Bargraph on Ajax Success Function in which the parameter is send need help.
Below are my code
On Page Load Code (It Runs Perfect)
<script>
var chart = $(function () {
$('#chart').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Overdue Projects'
},
xAxis: {
categories: <?php print_r(isset($project) ? $project : []); ?>
},
yAxis: {
title: {
text: 'Hours'
}
},
series: <?php print_r($series); ?>
}, function (chart) { // on complete
if (chart.series.length < 1) { // check series is empty
console.log('Data Empty');
chart.renderer.text('No Data Available', 380, 120)
.css({
color: '#4572A7',
fontSize: '16px'
})
.add();
}
});
});
</script>
On Ajax Success Function Code (Unable to Update the series and categories)
<script>
$("select[name=GraphPro]").on('change', function () {
var proId = $(this).val();
$.ajax({
data: 'proId=' + proId,
type: "post",
url: "<?php echo base_url('admin_dashboard/drawBarChart'); ?>",
dataType: "json",
success: function (xyz)
{
var project = xyz.project;
chart.series = xyz.series;
var chart1 = new Highcharts.Chart(chart);
}
})
})
</script>
Really hard to say for sure without seeing the data in your variables what you are aiming for with the project variable.
That said, to update the chart (read: change) you can do the following assuming chart is the variable of your already existing chart;
Updated as per your comment:
<script>
$("select[name=GraphPro]").on('change', function () {
var proId = $(this).val();
$.ajax({
data: 'proId=' + proId,
type: "post",
url: "<?php echo base_url('admin_dashboard/drawBarChart'); ?>",
dataType: "json",
success:function(xyz) {
console.log(xyz.project); //Value is ["Chat"]
console.log(xyz.series); // Value is [{"name":"Estimated Hours","data":[3]},{"name":"Consumed Hours","data":[12]}]
chart.update({
xAxis:{ categories: xyz.project //print as xyz.project instead of above project value
},
series: xyz.series // print as xyz.series instead of above series value
});
}
})
})
</script>
Highchart API on update: http://api.highcharts.com/class-reference/Highcharts.Chart#update
Working example using update when button is clicked: http://jsfiddle.net/ewolden/crhh39v6/
To add additional series to your chart you need to use addSeries, like this:
<script>
$("select[name=GraphPro]").on('change', function () {
var proId = $(this).val();
$.ajax({
data: 'proId=' + proId,
type: "post",
url: "<?php echo base_url('admin_dashboard/drawBarChart'); ?>",
dataType: "json",
success: function (xyz)
{
var project = xyz.project; //don't know what the plan with this variable is
chart.addSeries(xyz.series);
}
})
})
</script>
Highchart API on addChart: http://api.highcharts.com/class-reference/Highcharts.Chart#addSeries
I have a php, jquery, jqueryMobile, highcharts page with several charts on one page.
No i added an ajax call to load event to get live data into the charts. but i have to declare this in every Highcharts object, no matter which way i try it's not working as global function.
Here parts of the code i have and which is working
$(document).ready(function () {
// define sensorName
var sensorName = "rflinkstation";
chart1 = new Highcharts.chart({
"chart": {
"renderTo": sensorName,
"events": {
"load": function() {
var series = this.series[0];
setInterval(function() {
$.ajax({
url: 'sensorAjaxData.php',
success: function(point) {
console.log("ajax request for = " + sensorName);
// add the point
series.addPoint(point, true, true);
},
cache: false,
data: { "sensorName": sensorName,
"stationID": <?php echo $stationID;?>,
}
});
}, 60000);
}
}
},
"series": [{
...
$(document).ready(function () {
// define sensorName
var sensorName = "batteryvolt1";
chart2 = new Highcharts.chart({
"chart": {
"renderTo": sensorName,
"events": {
"load": function() {
var series = this.series[0];
setInterval(function() {
$.ajax({
url: 'sensorAjaxData.php',
success: function(point) {
console.log("ajax request for = " + sensorName);
// add the point
series.addPoint(point, true, true);
},
cache: false,
data: { "sensorName": sensorName,
"stationID": <?php echo $stationID;?>,
}
});
}, 60000);
}
}
},
"series": [{
....
What i try to achieve is to put the "load" function into a function to prevent copy pasting allot of code.
but if i declare something like
function getData(sensorName) {
and
events: { load: setInterval(getData(sensorName),6000) }
i loose the object and get this.series is undefined
My programming knoledge comes from pre object orinted programming and i do not fully understand the explanations in how to extend highcharts. Also the Highcharts live data example is written so that chart is a global variable and works only with one chart on a page.
so my question is how can i extend Highcharts with a load event that takes "sensorName" as argument and does an ajax call and insertrs the returned data into the right chart?
And a side question why is something like:
var series = this.series[0];
$.ajax({
...
series.addPoint(point)
...
working, and this not
$.ajax({
...
this.series[0].addPoint(point)
...
The this (Window object) inside of setInterval() function is not the same this (Chart object) as in chart.events.load() function. You can for example set the second parameter in getData() function which will indicate chart. Now getData() looks like this:
function getData(sensorName, chart) {
var series = chart.series[0];
$.ajax({
url: 'http://www.json-generator.com/api/json/get/bTNHrHVJmG?indent=2',
success: function(point) {
console.log('AJAX request for = ' + sensorName);
// add the point
series.addPoint(point, true, true);
},
data: {
sensorName: sensorName,
stationID: sensorName + 'ID' //<?php echo $stationID;?>,
},
cache: false
});
};
and it call in load event looks like this:
load: function() {
var chart = this;
setInterval(function() {
getData(chart.options.chart.renderTo, chart);
}, 5000);
}
Take a look at the example I prepared for you.
Example:
http://jsfiddle.net/a40qvy47/
I try to call a function within a JQuery ajax call, but it keeps showing me "TypeError: c.slice is not a function", I don't quite understand why this happens? I appreciate your help! Thank you in advance!
Here is my AJAX call:
$.ajax({
url: "my.php",
method: "get",
dataType: "json",
data: requestJSON,
success: function(jsondata){
$.getJSON('my.php?callback=?', function (data) {
// Create the chart
$('#historicalcharts').highcharts('StockChart', {
rangeSelector : {
selected : 1
},
title : {
text : 'AAPL Stock Price'
},
series : [{
name : 'AAPL Stock Price',
data : data,
type : 'area',
threshold : null,
tooltip : {
valueDecimals : 2
},
fillColor : {
linearGradient : {
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops : [
[0, Highcharts.getOptions().colors[0]],
[1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
}
}]
});
});
});
}
I try to mimic the function in this link, the only difference is that it retrieves the JSON data on each call, but I use a JSON data that I get from my php script.
http://www.highcharts.com/stock/demo/area
Here is my php code
<?php
if (isset($_GET['request'])) {
header("content-type: application/json");
$retrievechartJSON = 'http://dev.markitondemand.com/MODApis/Api/v2/InteractiveChart/json?parameters=' . $_GET['request'];
$json = file_get_contents($retrievechartJSON);
echo $_GET['callback']. '('. $json . ')';
?>
From HighCharts:
It is not possible to use the jQuery .getJSON() function on JSON files outside of your own domain. It is however possible to use JSONP.
You need to add a callback to your PHP, which wraps the JSON and then you return that JSON object:
Example:
<?php
header("content-type: application/json");
$array = array(7,4,2,8,4,1,9,3,2,16,7,12);
echo $_GET['callback']. '('. json_encode($array) . ')';
?>
With those changes you can use use jQuery's $.getJSON() like so:
var url = "http://url-to-your-remote-server/jsonp.php?callback=?";
$.getJSON(url, function(data) {
var yourJSONP = data;
// render you chart here
});
Here are the relevant docs for Cross Domain Data:
http://www.highcharts.com/docs/working-with-data/getting-data-across-domains-jsonp
I have url and i want to execute this url from cronjobs. in my php file there is javascript code to export highchart.
this is my code:
<script>
$(function () {
var options = {
title: {
text: 'Daily Chart',
x: -20 //center
},
exporting: {
url: 'http://export.highcharts.com/'
},
xAxis: {
categories: [
'A','B',
]
},
yAxis: {
title: {
text: 'IDR'
},
},
tooltip: {
valueSuffix: '°C'
},
series: [{
showInLegend: false,
name: 'Daily',
data: [
1,2
]
}]
};
var obj = {},
exportUrl = options.exporting.url;
obj.options = JSON.stringify(options);
obj.type = 'image/png';
obj.async = true;
var link=$.ajax({
type: 'post',
url: exportUrl,
data: obj,
dataType: 'html',
context: document.body,
global: false,
async:false,
success: function (data) {
var result=exportUrl+data;
return result;
}
}).responseText;
$.ajax({
type: 'get',
url: 'http://webserver2/index.php/report/render?link='+link+'&id=1',
data: link,
success: function (data2) {
//alert(data2);
}
});
});
</script>
If i execute it in my browser i will get file highcart.png to my server. But if i execute in cronjobs i get nothing. Any body know how to execute it with cronjobs??
JavaScript is a client-side language that runs from within a browser.
You can however use something like PhantomJS to run js from the server side.
Look at: http://phantomjs.org/
Edit:
Download the necessary package from here. Note that these are pre-compiled packages, we will assume you are using Linux.
You simply save the 'phantomjs' file in your filesystem somewhere (that you can access with crontab).
Save your javascript as a .js file extension.
Add a cron job like:
30 08 10 06 * /path/to/phantomjs javscriptfile.js
This will run 30 of June at 8.30am (You will need to schedule it when you want.)
Hopefully this should work as intended, although it does seem you are using jQuery functions so you might need to include the jQuery source code in your .js file.
I'm trying to create a web-page in EXTJs that has two major components:
A Form (Ext.form.Panel)
A Panel (Ext.tree.Panel)
The form is supposed to get some values, which should populate tree in second panel. In the button handler of the first panel I have access to the updated JSON object, but I cannot figure out a way to refresh the TreeStore that will update the display in tree.Panel.
This is what I have so far :
Ext.define('TreeServiceData',{
config:{
data : ''
},print : function() {
console.log("Printing data: ")
console.log(this.data.children[0])
}
});
var dataObject = Ext.create('TreeServiceData');
dataObject.setData({'expanded':false,'children':[{'text':'Master','expanded':true,'leaf':false,'children':[{'text':'Child 1','expanded':true,'leaf':false,'children':[{'text':'Child 2','expanded':true,'leaf':false,'children':[{'text':'Child 3','expanded':false,'leaf':false}]}]}]}]})
Ext.define('TreeStoreData',{
extend: 'Ext.data.TreeStore',
model: 'TaskModel',
autoLoad: true,
autoSync: true,
proxy: {
type:'memory',
reader: {
type:'json'
}
},
root:dataObject.getData()
});
var treeStore = Ext.create('TreeStoreData');
Now I'm trying to update and display the value of this treestore on a button call which looks like this :
buttons:[
{
text:'Get CCP/Product',
handler:function (btn, evt) {
dataObject.print();
treeStore.removeAll();
dataObject.setData({'expanded':false,'children':[{'text':'Master11','expanded':true,'leaf':false,'children':[{'text':'Child 12','expanded':true,'leaf':false,'children':[{'text':'Child 23','expanded':true,'leaf':false,'children':[{'text':'Child 34','expanded':false,'leaf':false}]}]}]}]})
dataObject.print();
}
}
]
But on this button handler I'm always getting a "Uncaught TypeError: Cannot call method 'indexOf' of undefined " on treeStore.removeAll() method, where treestore is clearly defined in this context.
Question 1) What is the correct way to refresh a TreeStore ?
Answer 1)
Instead of:
treeStore.removeAll();
dataObject.setData( ... );
You should do:
dataObject.setData( ... ); // This won't affect the store
treeStore.setRootNode(dataObject.getData()); // Actually update the store
Note that changing dataObject's data won't affect the store automatically like you seem to think...
this code works for me (ExtJS 4.2.1)
Total tree panel nodes refresh example:
var responseDictObjects = $.ajax({
data: { Id: this.idDictionary },
dataType: "json",
type: "POST",
cache: false,
url: 'http://' + config.domain + '/' + 'api/Dictionaries/GetDictTreeData',
async: false
}).responseText;
responseDictObjects = jQuery.parseJSON(responseDictObjects);
while (this.storeDict.getRootNode().firstChild) {
this.storeDict.getRootNode().removeChild(this.storeDict.getRootNode().firstChild);
}
this.storeDict.getRootNode().appendChild(responseDictObjects.Data);
Replace this.storeDict with your store reference.
In my case:
JSON.stringify(responseDictObjects.Data)
returns
"[{"id":8,"text":"kkk","leaf":false,"expanded":true,"children":null},{"id":17,"text":"ttttt","leaf":false,"expanded":true,"children":null},{"id":22,"text":"gggg","leaf":false,"expanded":true,"children":null},{"id":23,"text":"qqq","leaf":false,"expanded":true,"children":null},{"id":24,"text":"fff","leaf":false,"expanded":true,"children":null},{"id":27,"text":"fff","leaf":false,"expanded":true,"children":null},{"id":28,"text":"ggggggggggggggggggg","leaf":false,"expanded":true,"children":null},{"id":31,"text":"ttttttttttt666666666","leaf":false,"expanded":true,"children":null},{"id":32,"text":"ffffffffffffffffffff","leaf":false,"expanded":true,"children":null},{"id":33,"text":"kkkkkkkkkkkkk","leaf":false,"expanded":true,"children":null},{"id":35,"text":"7777777777","leaf":false,"expanded":true,"children":null},{"id":36,"text":"999999999999","leaf":false,"expanded":true,"children":null},{"id":37,"text":"iii","leaf":false,"expanded":true,"children":null}]"
I found another bug with TreePanel, previosly removed nodes appears after executing appendChild. So i started to use jquery tree plugin (dynatree). All you need is to create empty panel. And after render a panel, embed tree, in my case:
Create empty panel:
that.treePanel = Ext.create('Ext.panel.Panel', {
title: 'Records',
width: 350,
height: 400
});
After rendering panel you can refresh nodes whenever you want:
var that = this;
var responseDictObjects = $.ajax({
data: { Id: this.idDictionary },
dataType: "json",
type: "POST",
cache: false,
url: 'http://' + config.domain + '/' + 'api/Dictionaries/GetDictTreeData',
async: false
}).responseText;
responseDictObjects = jQuery.parseJSON(responseDictObjects);
var el = this.treePanel.getId();
if (this.treeDict == null) {
this.treeDict = $('#' + el).dynatree({
onActivate: function (node) {
that.treeDict.lastSelectedId = node.data.index;
},
children: []
});
}
this.treeDict.dynatree("getRoot").removeChildren(true);
this.treeDict.dynatree("getRoot").addChild(responseDictObjects.Data);