我试图在一个.data()
选择中使用两个不同的区域生成器,这样一组点可以有一个从上到下渲染的区域,而第二个区域的区域可以从左到右渲染。我可以将胖箭头函数传递给除“d”之外的每个.attr()
,这会产生以下错误:
Error: <path> attribute d: Expected moveto path command ('M' or 'm'), "function area(da…".
我需要访问选择索引才能从布尔数组中设置区域。 Please see the jsfiddle I've set up with the relevant code.我评论过两次尝试将函数传递给.attr('d')
。
答案 0 :(得分:0)
如果您检查生成的代码,您会看到:
所以,你没有提出价值观。而是调用函数。
将(d)
添加到返回值,以便执行区域生成器功能:
.attr('d', function(d, i){
if (horizontalNotVertical[i]) {
return horizontalArea(d);
} else {
return verticalArea(d);
}
})
答案 1 :(得分:0)
您的代码中的问题只是D3中着名的第一个参数。
您的comment:
我想知道为什么D3会自动执行区域生成器(
.attr('d', myArea)
),但如果区域生成器由匿名函数返回则不会自动执行...
不正确。 D3在执行函数返回的函数时没有问题。
当你这样做......
.attr('d', myArea)
...数据自动作为第一个参数传递给myArea
。我们来看一个基本演示:
var data = ["foo", "bar", "baz"];
var sel = d3.select("body").selectAll(null)
.data(data)
.enter()
.append("whatever")
sel.attr("whatever", callback)
function callback(d) {
console.log("The datum is " + d)
}
<script src="https://d3js.org/d3.v5.min.js"></script>
因此,如果要将myArea
函数放在匿名函数中,则必须指定第一个参数,因为该数据传递给外部函数,而不是myArea
:
.attr('d', function(d){
//1st arg here------^
myArea(d);
//and here-^
});
让我们看看:
var data = ["foo", "bar", "baz"];
var sel = d3.select("body").selectAll(null)
.data(data)
.enter()
.append("whatever")
sel.attr("whatever", function(d) {
callback(d);
})
function callback(d) {
console.log("The datum is " + d)
}
<script src="https://d3js.org/d3.v5.min.js"></script>
因此,在您的情况下,您只需要:
.attr('d', (d, i) => (horizontalNotVertical[i]) ? horizontalArea(d) : verticalArea(d));
只是为了表明D3在执行另一个函数返回的函数时没有问题,请看看最后一个片段:
var data = ["foo", "bar", "baz"];
var sel = d3.select("body").selectAll(null)
.data(data)
.enter()
.append("whatever")
sel.attr("whatever", function() {
callback();
})
function callback() {
console.log("I don't have the datum!")
}
<script src="https://d3js.org/d3.v5.min.js"></script>
以下是更新的jsfiddle:https://jsfiddle.net/zt5vxbm6/