Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在d3中,每个函数和这个关键字是如何协同工作的?【链接转换】_Javascript_D3.js_This_Each - Fatal编程技术网

Javascript 在d3中,每个函数和这个关键字是如何协同工作的?【链接转换】

Javascript 在d3中,每个函数和这个关键字是如何协同工作的?【链接转换】,javascript,d3.js,this,each,Javascript,D3.js,This,Each,我正在使用d3库,很难理解其中的一些构造,希望有经验的人能给我一些指导 <!DOCTYPE html> <html lang="en"> <head> <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> </head> <body> <script> var svg=d3.select("body"

我正在使用d3库,很难理解其中的一些构造,希望有经验的人能给我一些指导

<!DOCTYPE html>
<html lang="en">
  <head>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

  </head>
  <body>
  <script>
var svg=d3.select("body").append("svg").attr("width",800).attr("height",1000);
svg.selectAll("circle")
.data(d3.range(10)).enter().append("circle")
.attr("cx",function(d){return d;})
.attr("cy",function(d){return d*50;})
.attr("r",function(d){return d;})
.transition().duration(4000).style("fill","red")
.each("end",svg.selectAll(this).transition().duration(4000)
.attr("cx",function(d){return d*10;}));
</script>   
  </body>
  </html>

据我所知,这应该是创建圆,然后转换颜色以填充红色,然后更改每个圆的cx属性。至少,这是我想做的。有人能解释一下方法链接到底是如何工作的,以及如何使用each函数和this关键字吗?

在这种情况下,您的“this”将不会引用任何d3对象,因为this是在与标记相同的范围内计算的,在非严格模式下,它引用窗口对象

我建议你试着在没有过渡的情况下开始,然后在基本工作完成后逐渐添加过渡

代码的基本概要如下:

根据范围1-10生成数据集 为每个数据对象创建一个圆 所有对象都引用其各自的值,因此它们实际上是数字,用于计算它们的位置X、y和大小r 然后你转换他们的背景 然后告诉它监听一个结束事件并执行一段代码。 第五步是失败的地方。我认为这基本上就是你想要的:

var svg=d3.select("body").append("svg").attr("width",800).attr("height",1000);

svg.selectAll("circle")
   .data(d3.range(10))
   .enter()
      .append("circle") 
         .attr("cx",function(d){return d;})
         .attr("cy",function(d){return d*50;})
         .attr("r",function(d){return d;})
         .transition()
             .duration(4000)
             .style("fill","red")
             // attach a handler to all affected objects and listen
             // to the "end" event:
             .each("end", function() { console.log(this, arguments); })
         .transition()
             .duration(4000)
             .attr("cx",function(d){return d*10;})
             // do it again
             .each("end", function() { console.log(this, arguments); })
;
默认情况下,过渡效果是链接的,请参见

根据我的经验,为d3设计一个合理的缩进非常有帮助,因为它可以帮助您了解“范围”目前正在做什么


顺便说一句,你的代码中还没有随机组件,所以不要指望它会产生你没有告诉它的任何魔力

您回答此类问题的方式是在调试器中。为了完全确定答案,我提取了内联函数,可以在其中设置断点:

function resize() {
    svg.selectAll(this).transition().duration(4000) //set breakpoint here
        .attr("cx",function(d){return d*10;})
}  

var svg=d3.select("body").append("svg")
          .attr("width",800)
          .attr("height",1000);

svg.selectAll("circle")
    .data(d3.range(10)).enter().append("circle")
    .attr("cx",function(d){return d;})
    .attr("cy",function(d){return d*50;})
    .attr("r",function(d){return d;})
    .transition().duration(4000).style("fill","red")
    .each("end",resize);
设置断点时,您将看到它的值可能是您期望的值:当前DOM元素,一个“[object SVGCircleElement]”。您还可以检查参数,发现传递给resize的参数是d和i。这可能不是一个令人满意的答案,因为您的代码不工作

下一个问题可能是如何正确调整大小。我不知道为什么svg.selectAllthis不起作用,但是如果我们调用d3.selectthis,该方法确实可以正常工作

function resize(d,i) {
    d3.select(this).transition().duration(4000)
        .attr("cx",function(d){return d*10;})
}
如果要将resize放回内联,请不要忘记将参数设置为回调,而不是语句:

.each("end",function (d) { d3.select(this).transition().duration(4000).attr("cx",d*10) });
此外,您还可以看到,首选的文档是say chained transitions transition.transition。实现所需功能的标准方法只是链接转换:

.transition()
    .duration(4000)
    .style("fill","red")
.transition()
    .duration(4000)
    .attr("cx", function (d) { return d*10});

你有没有研究过我用下面的代码链接的转换。默认情况下它们是否已链接?我的印象是,任何新的转换都会抵消同一对象上以前正在进行的转换。svg.selectAllcircle.datad3.range10.enter.appendcircle.attrcx,functiond{return d;}.attrcy,functiond{return d*50;}.attrr,functiond{return d;}.transition.duration4000.stylefill,red.eachend,functiond{d3.selectthis.transition.duration4000.attrcx,functiond{return d*10;};谢谢gerard,你能告诉我为什么在每个函数的匿名函数中使用“this”关键字后,它的含义会发生变化吗。每个元素,函数d{d3.s‌​electthis.transition.duration4000.attrcx,函数d{return d*10;};这是由于javascript内部的原因,它指的是当前的函数范围,基本上可以是任何函数,这取决于库调用的实现方式。有关不同用途的详细说明,请参阅cases@GerardvanHeldenD3函数的内部定义和文档都很好,可以引用当前的DOM元素。在OP正在考虑的情况下,它将永远不会引用window。@Lars在开篇文章的代码段中提供的代码中它会引用,因为它不在函数内部。请注意你的陈述,否则可能会很混乱。