使用JSON将格式化JavaScript代码传递给HighCharts

时间:2014-10-20 17:59:42

标签: javascript ajax json highcharts

我有一个网站使用AJAX将JSON格式的字符串传递给HighCharts图表。

您可以将此视为中间的JSON代码部分:

http://jsfiddle.net/1Loag7pv/

$('#container').highcharts(

//JSON Start

{
"plotOptions": {
"series": {"animation": {"duration": 500}}
,"pie": {
"allowPointSelect": true,
"cursor": "pointer",
"dataLabels": {"formatter":function(){return this.point.name+': '+this.percentage.toFixed(1) + '%';}}
    }
},
"chart":{"renderTo":"divReportChart"}
,"title":{"text":"Sales Totals"}
,"xAxis":{"title":{"text":"Item"}, "categories":["Taxes","Discounts","NetSalesTotal"], "gridLineWidth":1}
,"yAxis":[{"title":{"text":"Amount"}, "gridLineWidth":1}]
,"series":[{"name":"Amount","type":"pie", "startAngle": -60,"yAxis": 0,"data":[["Taxes",17.8700],["Discounts",36.0000],["NetSalesTotal",377.9500]]}]
}

 //JSON end

);

问题在于功能部分......

“dataLabels”:{“formatter”:function(){return this.point.name +':'+ this.percentage.toFixed(1)+'%';}}

未通过JSON传输

所有研究都告诉我,没有办法做到这一点。

IE ... Is it valid to define functions in JSON results?

有人知道如何解决这个限制吗?

3 个答案:

答案 0 :(得分:3)

确实无法在JSON中传递函数。 Javascript是JSON的超集。

一种常见的方法是在javascript中定义图表(例如在页面加载期间),然后页面通过Ajax仅请求数据。返回数据后,可以在呈现之前或之后使用highcharts API将其添加到图表对象。

如果你真的想从带有图表的服务器传递格式化程序功能,请将其作为字符串发送,然后将其转换为如下函数:

var fn = Function(mystring);

并在高级图表中使用它,如:

chart.plotOptions.pie.dataLabels = {"formatter":fn};

我重新考虑了你的例子来展示这种方法:http://jsfiddle.net/wo7zn0bw/

答案 1 :(得分:1)

我有一个类似的难题。我想创建JSON服务器端(ruby on rails),这样我就可以为Web API创建图表图像,并使用相同的代码在客户端Web浏览器上显示它。这与SteveP的答案类似。

为符合JSON标准,我将所有格式化程序函数更改为字符串

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

在网络方面,我浏览哈希查找格式化程序键并使用此代码将其替换为函数(可能是更好的方法!?)。 的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;
    };

}

要使用它,将类似于 javascript

hashNavigator = new HashNavigator();
hashNavigator.navigateAndReplace(myHighchartsHash, "formatter")

此时,hash / js-object是Highcharts ready

类似的想法用于Web图像API。

我真的希望黑客攻击JSON不是唯一的解决方案,但它确实有效!

答案 2 :(得分:0)

我使用了不同的方法。我创建了一个类似下面的JSON

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

当我评估表达式时,我使用(假设'formatter'的值是 formatterValueString

formatterValueString = formatterValueString.replace('function()', '');
let opts = (new Function(formatterValueString)).call(this);
formatterValue = opts;

使用这种方法的原因是很难将'this'与函数绑定。 eval()函数在访问变量时效果不佳。我相信有办法做到这一点。只是觉得这很快。