Anna Jeanine Anna Jeanine - 1 month ago 28
JSON Question

Dynamically load in series HighCharts

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

Answer

In my project I have an object that encapsulates the highcharts object. And I have a couple of methods to add/remove series from it:

The wrapper object has an init method that takes your configuration, gets and injects element reference into it, and creates a new instance of hc.

var fcChart = function() {};

fcChart.prototype.init = function( id, cfg ){
    var element = $(id)[0];
    cfg.chart.renderTo = element;
    this.hc = new Highcharts.Chart(cfg);
}


// this.hc is a reference to highcharts object
fcChart.prototype.addSeries = function( seriesData ){
      // you may add false as a second parameter, to prevent chart redraw when I add series. I redraw it later. 
     this.hc.addSeries(seriesData /*,false */);
}

// removes all the series from the chart
fcChart.prototype.clearSeries = function( ){
    if( typeof this.hc !== "undefined" ) {
        while (this.hc.series.length > 0) {
            // false there is important if you dont want to redraw the whole chart after each removed series
            this.hc.series[0].remove(false);
        }

    }
}; 

fcChart.prototype.redraw = function( ){
    this.hc.redraw();
}

It worked for me.

Ofc, if you pass "false" as a redraw parameter to the methods above, then you have to call chart.redraw() at some point of time to render the results.

So, how to use all of above. Lets assume that you have an element "#chartId" in you html. And some chart configuration object "cfg".

to initialize a new chart wrapper object:

 var chart = new fcChart();
 chart.init('#chartId', cfg);

To clear the chart and add new series to it:

 chart.clearSeries();
 chart.addSeries( __whatever_series_data___);
 chart.addSeries( __whatever_series_data___);
 chart.addSeries( __whatever_series_data___);
 chart.redraw();

If you want to add series w/o clearing it, you do

 chart.addSeries( __whatever_series_data___);
 chart.redraw();
Comments