【问题标题】:How do your write a function that returns values from an array?你如何编写一个从数组返回值的函数?
【发布时间】:2017-05-28 23:20:21
【问题描述】:

我创建了这个数组:

var lineData = [ { "x": 25,   "y": 75},  { "x": 85,   "y": 130},
             { "x": 140,  "y": 190}, { "x": 195,  "y": 245},
             { "x": 195,  "y": 300}, { "x": 25,  "y": 350},
             { "x": 80,  "y": 405}, { "x": 195,  "y": 460}];

现在我想在数组中的坐标上绘制椭圆。如何创建将访问 x 和 y 值的函数?函数是如何工作的?

// Draw ellipses 
var circle = svgContainer.append("ellipse")
    .attr("cx", function(d) { return d.x; }})
    .attr("cy", function(d) { return d.y; })
    .attr("rx", 5)
    .attr("ry", 5);

【问题讨论】:

标签: javascript jquery d3.js


【解决方案1】:

在 D3 代码中使用循环访问数据(如在 accepted answer 中)是一个可怕的想法:这不仅完全没有必要,而且违背了 D3 的概念数据连接,以后会变得很尴尬(如果您尝试操纵/更改该选择)。如果您将通过循环解决此问题,那么您为什么首先使用 D3?您接受的解决方案是完全非惯用的

不需要循环。只需绑定数据并使用“输入”选择,使用匿名函数的第一个参数访问每个圆的数据:这就是 D3 中著名的function(d)。当你这样做时......

.attr("cx", function(d){ return d.x})
//first parameter ---^

... 每个元素的数据将传递给attr 函数。如果您想知道,第二个参数是索引,第三个参数是当前组。此外,参数的实际名称并不重要,重要的是它的顺序。

这是一个使用您的数据的示例:

var svg = d3.select("body")
  .append("svg")
  .attr("width", 600)
  .attr("height", 500);
  
var lineData = [ { "x": 25,   "y": 75},  { "x": 85,   "y": 130},
  { "x": 140,  "y": 190}, { "x": 195,  "y": 245},
  { "x": 195,  "y": 300}, { "x": 25,  "y": 350},
  { "x": 80,  "y": 405}, { "x": 195,  "y": 460}];
             
var ellipses = svg.selectAll("faraday")
  .data(lineData)
  .enter()
  .append("ellipse")
  .attr("cx", function(d){ return d.x})
  .attr("cy", function(d){ return d.y})
  .attr("rx", 5)
  .attr("ry", 5)
  .attr("fill", "teal");
<script src="https://d3js.org/d3.v4.min.js"></script>

【讨论】:

  • 好的,我试过你的答案,它也有效。拥有svg.selectAll("faraday") 的目的是什么?据我了解,要绘制椭圆,您将使用 svg.append("ellipse")
  • 尊重其他用户(这不是个人的),我的回答不是“也有效”:我的回答中的代码是 惯用的 D3。关于“法拉第”,由于您可以选择输入选择中不存在的东西(have a look here),因此我向每个 S.O. 中的不同科学家致敬。我写的sn-p。而且,如您所见,我们不必在输入选择中使用selectAll("ellipse") 来附加椭圆。
  • @GerardoFurtado 首先,你是绝对正确的,这是要走的路!不过,关于你获取空选项的方式,我有点不安。我在你最近的一些 sn-ps 中看到了你对科学家的引用,并且一直认为,他们提出的问题可能比他们实际回答的要多。如果 Mike Bostock 在他的 Blocks 中做了这种事情,我会感谢他的小难题以及通过追踪它获得的见解。然而,在这样的问答网站上,我认为大多数寻找问题答案的人都不会明白双关语。这……
  • @altocumulus 再想一想,我喜欢selectAll(null)... 我认为它更好地告诉新手 OP,输入选择不需要匹配任何 DOM 元素。从现在开始我将使用selectAll(null)
  • @GerardoFurtado Plus,速度更快:jsperf.com/d3-empty-selection。请注意测试的细节,因为我专门为你组装了这个;-)
【解决方案2】:

您可以使用forEach 方法遍历数组中的每个元素并获取每个元素中的值。

lineData.forEach(function(d) {
    // Draw an elipse
});

将您的代码放在括号内,使用d.xd.y 访问数组中每个元素的坐标。

【讨论】:

  • 谢谢! function(d) 的目的是什么? “d”代表什么,有什么作用?
  • @marcos forEach 将为数组中的每个元素执行一个作为参数赋予它的函数,并将数组中的元素之一传递给该函数。在这种情况下,我们将一个匿名函数 (function(d) {}) 传递给它,forEach 将数组中的第一个元素传递给我们的匿名函数,因此 d 现在等于数组中的第一个元素(然后它循环并遍历数组中的每个元素)。然后,您可以运行您的代码并根据 d 的任何内容对其进行操作。
猜你喜欢
  • 1970-01-01
  • 2012-12-25
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
相关资源
最近更新 更多