我有一个网站使用AJAX将JSON格式的字符串传递给HighCharts图表。
您可以将此视为中间的JSON代码部分:
$('#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?
有人知道如何解决这个限制吗?
答案 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()函数在访问变量时效果不佳。我相信有办法做到这一点。只是觉得这很快。