AngularJS和D3-JavaScript RangeError:递归中超出了最大调用堆栈大小
请参见下面的编辑 我编写了一个递归解析solr facet.pivot输出的函数,并将其转换为可以输入d3的sunburst图表的内容。一切正常,但我得到了其中一个,我不知道如何去做AngularJS和D3-JavaScript RangeError:递归中超出了最大调用堆栈大小,javascript,angularjs,d3.js,solr,Javascript,Angularjs,D3.js,Solr,请参见下面的编辑 我编写了一个递归解析solr facet.pivot输出的函数,并将其转换为可以输入d3的sunburst图表的内容。一切正常,但我得到了其中一个,我不知道如何去做 RangeError: Maximum call stack size exceeded 这是一个带有一些额外语句的函数,以提高可读性 this.get_facet_pivot_sunburst = function(field, data) { if (!field) { return
RangeError: Maximum call stack size exceeded
这是一个带有一些额外语句的函数,以提高可读性
this.get_facet_pivot_sunburst = function(field, data) {
if (!field) {
return {};
} else {
if (!data) {
data = response['facet_counts']['facet_pivot'][field];
}
var ops = 0;
var d = parse_facet_pivot(data);
console.log("Operations" + ops);
return d;
}
function parse_facet_pivot(data){
var out = {'name' : 'root', 'children': []};
for (ob in data) {
ops++;
out.children.push(parse_item(data[ob]));
}
return out;
}
function parse_item (doc) {
ops++;
var t = {'name' : doc.value, 'size' : doc.count, 'children': []};
for (piv in doc.pivot) {
t.children.push(parse_item(doc.pivot[piv]));
}
return t;
}
}
我在网上读到,它可能与将一个大对象传递给一个方法或重递归有关,但是我试图将数据限制在一个小的子集上,我仍然会遇到这个错误。在这种情况下,记录器将12打印为操作数,但通常在300-400之间
为了提供更多的背景信息,它在angularjs服务中运行,以提供一个使用d3绘制sunburst的指令。正如我之前提到的,图表画得很好,但我仍然得到这个
编辑:
看起来递归很好,问题在角度和D3的某个地方。下面是一个js提琴,演示了这个问题(在控制台日志中)。但是,请注意,在我的环境中,由于某些原因,我没有得到摘要错误
您的
doc
结构可能有一个循环。在像您这样的数据结构中,循环是一个参考链,它引导并(最终)回到起点。在您的例子中,如果一个pivot
数组以某种方式包含了一个指向结构顶部的“doc”对象的引用
作为一个实验,您可以为每个“doc”对象添加一个“标记”。如果您输入带有标记已设置的“doc”对象的parse_item()
,则您知道您遇到了一个循环:
function parse_item (doc) {
if (doc["@tag"]) throw new Error("Cycle detected");
doc["@tag"] = true;
ops++;
var t = {'name' : doc.value, 'size' : doc.count, 'children': []};
for (piv in doc.pivot) {
t.children.push(parse_item(doc.pivot[piv]));
}
return t;
}
您的
doc
结构可能有一个循环。在像您这样的数据结构中,循环是一个参考链,它引导并(最终)回到起点。在您的例子中,如果一个pivot
数组以某种方式包含了一个指向结构顶部的“doc”对象的引用
作为一个实验,您可以为每个“doc”对象添加一个“标记”。如果您输入带有标记已设置的“doc”对象的parse_item()
,则您知道您遇到了一个循环:
function parse_item (doc) {
if (doc["@tag"]) throw new Error("Cycle detected");
doc["@tag"] = true;
ops++;
var t = {'name' : doc.value, 'size' : doc.count, 'children': []};
for (piv in doc.pivot) {
t.children.push(parse_item(doc.pivot[piv]));
}
return t;
}
您的
doc
结构可能有一个循环。在像您这样的数据结构中,循环是一个参考链,它引导并(最终)回到起点。在您的例子中,如果一个pivot
数组以某种方式包含了一个指向结构顶部的“doc”对象的引用
作为一个实验,您可以为每个“doc”对象添加一个“标记”。如果您输入带有标记已设置的“doc”对象的parse_item()
,则您知道您遇到了一个循环:
function parse_item (doc) {
if (doc["@tag"]) throw new Error("Cycle detected");
doc["@tag"] = true;
ops++;
var t = {'name' : doc.value, 'size' : doc.count, 'children': []};
for (piv in doc.pivot) {
t.children.push(parse_item(doc.pivot[piv]));
}
return t;
}
您的
doc
结构可能有一个循环。在像您这样的数据结构中,循环是一个参考链,它引导并(最终)回到起点。在您的例子中,如果一个pivot
数组以某种方式包含了一个指向结构顶部的“doc”对象的引用
作为一个实验,您可以为每个“doc”对象添加一个“标记”。如果您输入带有标记已设置的“doc”对象的parse_item()
,则您知道您遇到了一个循环:
function parse_item (doc) {
if (doc["@tag"]) throw new Error("Cycle detected");
doc["@tag"] = true;
ops++;
var t = {'name' : doc.value, 'size' : doc.count, 'children': []};
for (piv in doc.pivot) {
t.children.push(parse_item(doc.pivot[piv]));
}
return t;
}
我也有同样的问题,这是我想到的 错误的原因是双向绑定、监视表达式和布局函数(d3.layout.partition())的组合。在本例中,您使用双向数据绑定在指令的内部范围中定义了属性“data”,并为该范围变量定义了watch表达式。在watch回调中,通过传递内部作用域的相同“data”属性来调用呈现函数 然后,该数据将在渲染函数中使用,该函数使用分区布局计算坐标以显示数据。计算出的坐标(x、y,可能还有几个分区布局的参数)作为新属性添加到输入数据结构中的每个元素中 长话短说:scope.data对象在渲染函数中更新,并触发再次调用渲染函数的监视回调 我不确定解决这一问题的最佳方法是什么,但这里有几个对我都有效的解决方案:
我也有同样的问题,这是我想到的 错误的原因是双向绑定、监视表达式和布局函数(d3.layout.partition())的组合。在本例中,您定义了属性“data”在指令的内部作用域中使用双向数据绑定并为该作用域变量定义watch表达式。在watch回调中,通过传递内部作用域的相同“data”属性来调用呈现函数 然后,该数据将在渲染函数中使用,渲染函数使用分区布局计算坐标以显示数据。计算出的坐标(x、y,分区布局可能还有几个参数)将作为新属性添加到输入数据结构中的每个元素中 长话短说:scope.data对象在渲染函数中更新,并触发再次调用渲染函数的监视回调 我不确定解决这一问题的最佳方法是什么,但这里有几个对我都有效的解决方案:
我也有同样的问题,这是我想到的 错误的原因是两个因素的组合