I'm working on creating a dynamically created chart that will add a series if there isn't one and if there is one add a point. I'm getting an Uncaught TypeError: Cannot call method 'addSeries' of undefined. I've looked around and I can't find why it says that method is undefined.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript" src="highcharts.js"></script>
$(document).ready(function () {
var chart1 = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column',
events: {
load: requestData
}
},
title: {
text: 'Survey Chart'
},
xAxis: {
categories: [],
title: {
text: 'Question Number'
}
},
yAxis: {
title: {
text: 'Total Answered'
}
},
legend: {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: 100,
y: 70,
floating: true
},
series: []
});
with the document ready function taking up the entire script i have the following functions
function requestData() {
ajaxCall(chartCreate, createSeries, "services/Survey.svc/DoWork", "{}");
chart1.redraw();
};
function chartCreate(point) {
var temp;
temp = $.parseJSON(point.d);
$.each(temp, function (key, p) {
var seriesObj;
seriesObj = seriesExists(p.mcAnswer);
if (seriesObj.status == false) {
chart1.addSeries({name: '' + p.mcAnswer + '', data: [] });
chart1.series[seriesObj.count].addPoint(p.total, false);
} else {
chart1.series[seriesObj.count].addPoint(p.total, false);
}
});
};
//loops through all the series to see if the series exists.
//if true returns index and true if not just returns false
function seriesExists(name) {
var ct = 0;
//var len = chart1.series.length;
var len = 0;
if (len > 0) {
$.each(chart1.series, function (count, curSeries) {
if (curSeries.name == name) {
return { 'count': count, 'status': true };
}
ct = count;
});
}
return { 'count': ct, 'status': false };
}; function createSeries() {
alert("error");
};
//$.ajaxCall({successFun: function, errorFun: function, source: "", data: {}});
function ajaxCall(myFunSuccess, myFunError, url, data) {
//chart1 = chartTemp;
$.ajax({
type: "POST",
async: false,
url: url,
data: data,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: myFunSuccess,
error: myFunError
});
//return chart1;
};
I'm able to use the ajax function call fine it's when I get to my chartCreate where I run into the problem.
The problem is that you're trying to add the serie before chart1 get your chart reference. That's why chart1 doens't have addSeries method.
You can see this issue here.
To fix it you can set manually the chart reference to chart1 before call requestData.
Like the following.
load: function() {
chart1 = this; // `this` is the reference to the chart
requestData();
}
Related
I am trying to poll my data in HighCharts. The graph in this link is what I am trying to achieve. I am using Ajax request to retrieve my data. Here is my code:
setInterval(RefreshGraph, 3000);
...
...
function RefreshGraph() {
var options = {
chart: {
type: 'spline'
},
title: {
text: 'Text'
},
xAxis: {
title: {
text: 'TIMEFRAME'
},
categories: ['-4m', '-3m', '-2m', '-1m', 'Now']
},
yAxis: {
title: {
text: 'NUMBER'
},
},
tooltip: {
crosshairs: true,
shared: true
},
plotOptions: {
spline: {
marker: {
radius: 4,
lineColor: '#666666',
lineWidth: 2
}
}
},
series: [{}]
};
Highcharts.ajax({
url: "/Home/GetData",
success: function (data) {
var formattedData = FormatData(data);
//Graph 1
options.series[0] = formattedData[0];
//Graph 2
options.series[1] = formattedData[1];
Highcharts.chart("container", options);
}
});
}
However, the entire graph gets redrawn with my above code. How can I enable live polling for the above code?
You create a chart every time data is received. You need to create a chart and then update it. Example:
const options = {...};
const chart = Highcharts.chart("container", options);
function RefreshGraph() {
Highcharts.ajax({
url: "/Home/GetData",
success: function(data) {
var formattedData = FormatData(data);
chart.update({
series: [formattedData[0], formattedData[1]]
});
}
});
}
setInterval(RefreshGraph, 3000);
Live demo: http://jsfiddle.net/BlackLabel/6d5stjab/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Chart#update
I have an .aspx file which has drop-down lists and on selected index changed a javascript function is being called to update the series data points on a highchart rather than rendering the entire chart again. I have created the below function but this doesnt seem to be updating the highchart table.It works when updating the chart.
Used this example to create the chart and table that synchronize together:
https://www.highcharts.com/blog/tutorials/synchronize-selection-bi-directionally-between-chart-and-table/
But when I click an item on the dropdown which refreshes the points using setData the table is not updating the values!!!
function salesPurchaseScatter() {
console.log("I am in the function");
var scatterData = [];
var xAxisLabels = [];
var scatterDatas;
$.ajax({
type: "POST",
async: false,
url: "Index.aspx/ReturnData",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
scatterDatas = data.d;
}
});
const chart = window.chart;
console.log("CHart: ", chart);
chart.series[0].setData(scatterDatas.map(item => item["bucket5"]));
chart.series[1].setData(scatterDatas.map(item => item["bucket10"]));
chart.series[2].setData(scatterDatas.map(item => item["bucket15"]));
chart.series[3].setData(scatterDatas.map(item => item["bucket20"]));
chart.series[4].setData(scatterDatas.map(item => item["bucket25"]));
chart.series[5].setData(scatterDatas.map(item => item["bucket30"]));
chart.viewData();
}
The above is not updating the data points on the data table!
My original function to create the chart in the first place which works fine is below:
var scatterData = [];
var xAxisLabels = [];
var scatterDatas;
$.ajax({
type: "POST",
async: false,
url: "Index.aspx/ReturnData",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
scatterDatas = data.d;
}
});
let chart = Highcharts.chart('container1', {
chart: {
type: 'scatter',
events: {
selection: selectPointsByDrag,
click: unselectByClick
},
// necesssary to be able to select by dragging
zoomType: 'xy'
},
title: {
text: '(' + minDWT + ' <DWT ' + ' < ' + maxDWT + ')',
style: {
fontWeight: 'bold',
fontSize: '20px'
}
},
plotOptions: {
scatter: {
lineWidth: 2,
dashStyle: 'dot'
},
series: {
connectNulls: true,
allowPointSelect: true,
pointPadding: 0,
point: {
events: {
select: function (e) {
selectTableCell(this, true);
},
unselect: function (e) {
selectTableCell(this, false);
}
}
},
marker: {
states: {
select: {
fillColor: 'tomato',
borderColor: 'green'
}
}
}
}
},
series: [{
name: 'bucket5',
data: scatterDatas.map(item => item["bucket5"]),
turboThreshold: 0,
id: 'Results1',
marker: {
symbol: 'circle'
},
},
{
name: 'bucket10',
data: scatterDatas.map(item => item["bucket10"]),
turboThreshold: 0,
id: 'Results2',
marker: {
symbol: 'circle'
},
},
{
name: 'bucket15',
data: scatterDatas.map(item => item["bucket15"]),
turboThreshold: 0,
id: 'Results3',
marker: {
symbol: 'circle'
},
},
{
name: 'bucket20',
data: scatterDatas.map(item => item["bucket20"]),
turboThreshold: 0,
id: 'Results4',
marker: {
symbol: 'circle'
},
},
{
name: 'bucket25',
data: scatterDatas.map(item => item["bucket25"]),
turboThreshold: 0,
id: 'Results5',
marker: {
symbol: 'circle'
},
}, {
name: 'bucket30',
data: scatterDatas.map(item => item["bucket30"]),
turboThreshold: 0,
id: 'Results6',
marker: {
symbol: 'circle',
fillColor: 'red',
radius: 10
},
}],
xAxis: {
categories: scatterDatas.map(item => item["date"])
},
tooltip: {
formatter: function () {
var s = '<span style="color:' + this.point.color + '">\u25CF</span> ' + this.point.series.name + '<br /><b>Date: ' + this.x + '</b><br/><b>Sales Price: ' + this.y + '</b>';
return s;
}
},
exporting: {
showTable: true
},
});
UPDATE:
I have managed to get a step further. The chart is updating with the new data points but the table is not :
exporting: {
showTable: true
},
The fix i put in place:
const chart = window.chart;
console.log("CHart: ", chart);
for (i = 0; i < chart.series.length; i++) //Added this
chart.series[i].setData([]);
chart.series[0].setData(scatterDatas.map(item => item["bucket5"]));
chart.series[1].setData(scatterDatas.map(item => item["bucket10"]));
chart.series[2].setData(scatterDatas.map(item => item["bucket15"]));
chart.series[3].setData(scatterDatas.map(item => item["bucket20"]));
chart.series[4].setData(scatterDatas.map(item => item["bucket25"]));
chart.series[5].setData(scatterDatas.map(item => item["bucket30"]));
chart.viewData();
chart.redraw(); //Added this
Have i missed something out? Struggling to debug and identify what is going wrong
Found a JSFiddle which is similar to my current set up. http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/export-data/showtable/
The above JS Fiddle has a similar chart and table output. When i click on a drop down item I am trying to setData (the data point values) as per above code and this should update the chart and table. In my case it is only updating the chart and not the table. The function I am calling is salesPurchaseScatter on dropdown selected index changed event.
ATTEMPTED THIS:
const table = window.table;
table.series[0].setData(scatterDatas.map(item => item["saleagebucket5"]));
table.series[1].setData(scatterDatas.map(item => item["saleagebucket10"]));
table.series[2].setData(scatterDatas.map(item => item["saleagebucket15"]));
table.series[3].setData(scatterDatas.map(item => item["saleagebucket20"]));
table.series[4].setData(scatterDatas.map(item => item["saleagebucket25"]));
table.series[5].setData(scatterDatas.map(item => item["imo"]));
chart.redraw();
table.redraw();
but series is not possible using a table. How can i update the data using setData for the table? I tried using chart.viewData() but this doesnt seem to work either.
My guess is: const chart= window.chart; is only referring to the chart but dont know how to re-do the entire high chart canvas just the chart on it own!
A JSFiddle I tried to follow - https://jsfiddle.net/hxgp0yvj/
but same issue happening- Table not updating in this but chart does. I moved the code into my own solution to test it out. What am i missing?
Thank you for sharing it, after digging into I found out that it is a regression. I reported it on the Highcharts GitHub issue channel where you can follow this thread. If you don't need any new functionalities please use the previous version of the Highcharts until the bug will be fixed.
https://github.com/highcharts/highcharts/issues/14320
I have a chart and my system that I need it to report the exact value of the search results.
Due to many data, the results come out so 1.1K.
In the place that 1.1K wanted it shows the exact value that would be 1057.
Here is the graph function in JS:
function Post(url, param, title, totalText) {
totalText = totalText || "Total";
$.ajax({
method: "POST",
url: "/Graficos/" + url,
data: param,
beforeSend: function () {
showLoader();
},
success: function (data) {
ChartConstructor(title, JSON.stringify(data), totalText);
},
complete: function () {
hideLoader();
}
});
}
function ChartConstructor(title, dados, totalText) {
window.google.charts.load('current', { 'packages': ['bar'] });
window.google.charts.setOnLoadCallback(drawStuff);
function drawStuff() {
var table = JSON.parse(dados);
var rows = "";
var array = [["", "Total"]];
for (var i = 0; i < table.length; i++) {
array.push([table[i].Title, table[i].Count]);
}
var data = new google.visualization.arrayToDataTable(array);
var options = {
width: '100%',
height: 400,
chart: {
title: title,
},
bar: { groupWidth: '95%' },
bars: 'horizontal',
series: {
0: { axis: 'distance' },
}
};
var chart = new google.charts.Bar(document.getElementById("chart-content"));
chart.draw(data, options);
$("#chart-type").val("");
}
}
According to the documentation, you can set the format of hAxis or vAxis to 'none' to display the full number.
Example:
var options = {
width: '100%',
height: 400,
chart: {
title: title,
},
bar: { groupWidth: '95%' },
bars: 'horizontal',
series: {
0: { axis: 'distance' },
},
vAxis: {
format: 'none'
}
};
I am trying to dynamically load in a number of series, depending on projects chosen by the user. I am using Laravel 5.2, PHP 5.6 and HighCharts.
I have managed to load in one JSON file, which is generated when the user selects projects. But I would like it if the JavaScript could parse the different series from the JSON file and dynamically load this into the series.
This is the code which I am using:
$(function () {
// Set up the chart
var processed_json = new Array();
$.getJSON('/uploads/test.json', function(data) {
for (i = 0; i < data.length; i++) {
processed_json.push([data[i].key, data[i].value]);
}
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column',
options3d: {
enabled: true,
alpha: 0,
beta: 0,
depth: 0,
viewDistance: 25
}
},
title: {
text: 'Grades'
},
subtitle: {
text: 'Dataset'
},
plotOptions: {
column: {
depth: 0
}
},
series: [{
name: 'Grades',
data: processed_json
}],
credits: {
enabled: false
}
});
function showValues() {
$('#alpha-value').html(chart.options.chart.options3d.alpha);
$('#beta-value').html(chart.options.chart.options3d.beta);
$('#depth-value').html(chart.options.chart.options3d.depth);
}
// Activate the sliders
$('#sliders input').on('input change', function () {
chart.options.chart.options3d[this.id] = this.value;
showValues();
chart.redraw(false);
});
showValues();
});
});
My JSON is formatted like:
[{"key":"Math","value":6},{"key":"Biology","value":"8"},{"key":"English","value":"7"},{"key":"Gym","value":"4"}]
So I would like to have more JSONs like so, in one file to be parsed in the Javascript and be loaded in into the series.
Thank you!
EDIT
thanks for your reply. I have edited my code:
$(function () {
var processed_json = new Array();
var options = {
chart: {
renderTo: 'container',
type: 'column',
options3d: {
enabled: true,
alpha: 0,
beta: 0,
depth: 0,
viewDistance: 25
}
},
title: {
text: 'Grades'
},
subtitle: {
text: 'Dataset'
},
plotOptions: {
column: {
depth: 0
}
},
series: [{
}],
credits: {
enabled: false
}
};
$.getJSON('/uploads/test.json', function(data) {
for (i = 0; i < data.length; i++) {
processed_json.push([data[i].key, data[i].value]);
}
});
options.series[0].remove();
options.series[0].setData = {
name: 'Grades',
data: processed_json
}
var chart = new Highcharts.Chart(options);
chart.redraw(true);
function showValues() {
$('#alpha-value').html(chart.options.chart.options3d.alpha);
$('#beta-value').html(chart.options.chart.options3d.beta);
$('#depth-value').html(chart.options.chart.options3d.depth);
}
// Activate the sliders
$('#sliders input').on('input change', function () {
chart.options.chart.options3d[this.id] = this.value;
showValues();
chart.redraw(false);
});
showValues();
});
But nothing is displayed anymore and the following error is given
TypeError: options.series[0].remove is not a function
I have also tried
var chart = new Highcharts.Chart(options);
chart.series[0].remove();
chart.series[0].setData = {
name: 'Grades',
data: processed_json
}
chart.redraw(true);
But this gives:
TypeError: Cannot set property 'setData' of undefined
I think highcharts has a method chart.addSeries for adding a new series. If you want to replace the current series with a new series, you can try removing first the current series using chart.series[0].remove( ) then add the new series with chart.addSeries. The parameter for the chart.addSeries can be an object like your
{
name: 'Grades',
data: processed_json
}
Then, define method with load data.. example:
function(chart) {
$.each(chart.series, function(i, v){
chart.series[i].remove(true);
});
chart.addSeries({your_data}, true);
}
check http://api.highcharts.com/highcharts/Chart.addSeries/Chart.addSeries
In my webapp, i use 10 of 15 types of graphs highchart and all dynamically load and work fine :) Highcharts is awesome.
I am working with Highcharts and live data. I have my ajax all set up properly it seems and have a setTimeout called to bring in live data. Whenever that data comes in I want to addPoint() to my series and draw the new graph (shifting to the left). Below is my code, line 85 is the .addPoint call but you will see in the console that it is showing as not a function or undefined.
I know from the console as well that I am a calling my data correctly from my chart (chart1.data.series[0] returns and object). Here is the highcharts documentation on series data and addPoint : < http://api.highcharts.com/highcharts#Series.addPoint >
Any idea where I went wrong? I am new to js 1 year <. so I appreciate all your help!
<!doctype html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
</head>
<body>
<div id="container" style="width:100%"></div>
</body>
<script>
chart1 = {
yAxisMin: null,
yAxisMax: null
};
// empty objects for our data and to create chart
seriesData = [];
BPM = [];
time1 = [];
// console.log(chart1.data.series);
$(function() {
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
function requestData() {
var url = 'http://msbandhealth.azurewebsites.net/odata/PulsesAPI/';
$.ajax({
url: url,
dataType: 'json',
context: seriesData,
success: function(data) {
shift = chart1.data.series[0].data.length > 20;
// structure our data
for (var i = 0; i < data.value.length; i++) {
bpm = data.value[i].BPM;
time = data.value[i].Time;
console.log(time);
this.push([time, BPM]);
BPM.push(bpm);
time1.push(time);
}
// console.log(series[0]);
// find the highest pulse so we can set it to the highest y point
chart1.yAxisMax = (function(array) {
var pulse_array = [];
for (var i = 0; i < array.length; i++) {
if (array[i] != null) {
pulse_array.push(array[i]);
}
}
return Math.max.apply(Math, pulse_array);
})(BPM);
// find the lowest pulse rate and set it to lowest y point
chart1.yAxisMin = (function(array) {
var pulse_array = [];
for (var i = 0; i < array.length; i++) {
if (array[i] != null) {
pulse_array.push(array[i]);
}
}
return Math.min.apply(Math, pulse_array);
})(BPM);
// set our data series and create new chart
chart1.data.series[0].data = BPM;
chart = new Highcharts.Chart(chart1.data);
$('#container').css({
height: '400px'
});
chart1.data.series[0].addPoint(BPM, true, true);
// setTimeout(requestData, 3000);
console.log(chart1.data.series);
}
});
}
// give highcharts something to render to
container = document.getElementById("container");
chart1.data = {
chart: {
renderTo: container,
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: requestData()
}
},
title: {
text: ' Real Time Pulse Analysis'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
min: chart1.yAxisMin,
max: chart1.yAxisMax,
title: {
text: 'Heart Rate'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Beats Per Minute',
data: []
}]
};
});
});
</script>
</html>
You should use reference to chart and then call addPoint, instead of refer to chart configuration object.
Correct form: chart.series[0].addPoint()