score:3

Accepted answer

it is true that you cannot pass functions in json. javascript is a superset of json.

a common approach is for the chart to be defined in javascript (e.g. during the page load), and the page then requests just the data via ajax. when the data is returned it can be added to the chart object, either before it is rendered or afterwards using the highcharts api.

if you really want to pass the formatter function from the server with the chart, send it as a string, and then turn it into a function like this:

var fn = function(mystring);

and use it in highcharts like:

chart.plotoptions.pie.datalabels = {"formatter":fn};

i've re-factored your example to show the approach: http://jsfiddle.net/wo7zn0bw/

score:0

i used a different approach. i created a json like below

{"formatter": "function(){ return this.point.name+':'+this.percentage.tofixed(1) + '%';}"}

when i came to evaluating the expression, i used (assuming that the value of the 'formatter' is formattervaluestring)

formattervaluestring = formattervaluestring.replace('function()', '');
let opts = (new function(formattervaluestring)).call(this);
formattervalue = opts;

the reason to use this approach was it became hard to bind 'this' with the function. the eval() function did not go well with accessing variable this. i am sure there are ways to do it. just thought this was quick.

score:2

i had a similar conundrum. i wanted to create the json server side (ruby on rails) so i could create images of charts for a web api and also present it on the client web browser with the same code. this is similar to stevep's answer.

to conform with json standards, i changed all formatter functions to strings

{"formatter": "function(){ return this.point.name+':'+this.percentage.tofixed(1) + '%';}"}

on the web side, i navigate the hash looking for formatter keys and replace them with the function using this code (may be a better way!?). javascript:

function hashnavigator(){

    this.navigateandreplace = function(hash, key){
        if (!this.isobject(hash)){
            //nice if only navigated hashes and arrays
            return;
        }

        var keys = object.keys(hash);
        for(var i = 0; i< keys.length; i++){
            if (keys[i] == key){
                //convert string to js function
                hash[keys[i]] = this.parsefunction(hash[keys[i]]);
            } else if (this.isobject(hash[keys[i]])){
                //navigate hash tree
                this.navigateandreplace(hash[keys[i]], key);
            } else {
                //continue
            }
        }
    };

    this.isobject = function(testvar) {
        return testvar !== null && typeof testvar === 'object'
    }

    //http://stackoverflow.com/questions/7650071/is-there-a-way-to-create-a-function-from-a-string-with-javascript
    this.parsefunction = function(fstring){
        var funcreg = /function *\(([^()]*)\)[ \n\t]*{(.*)}/gmi;
        var match = funcreg.exec(fstring.replace(/\n/g, ' '));

        if(match) {
            return new function(match[1].split(','), match[2]);
        }

        return null;
    };

}

to use this, would be something similar to this javascript:

hashnavigator = new hashnavigator();
hashnavigator.navigateandreplace(myhighchartshash, "formatter")

at that point the hash/js-object is highcharts ready

similar idea was used for the web image api.

i was really hoping that hacking at the json was not the only solution, but it works!


Related Query

More Query from same tag