正确使用 D3 “data” 方法,并传递函数和数据集
Properly using D3 `data` method with a function and data set passed
D3教程(部分)损坏
在我看来,D3 中似乎发生了一些变化。
我这样说是因为,当我试图更好地理解数据绑定方法时,我查看了 Mike Bostock 的选择教程页面。 这个页面本身不能完全工作(不再),我敢肯定,当他制作它时它工作得很好!!
例:
大约 3/4 的页面,给出了以下代码示例:
var letters = [
{name: "A", frequency: .08167},
{name: "B", frequency: .01492},
{name: "C", frequency: .02780},
{name: "D", frequency: .04253},
{name: "E", frequency: .12702}
];
function name(d) {
return d.name;
}
d3.selectAll("div").data(letters, name);
如果我完全在页面本身的控制台中运行它,我会在控制台中得到以下内容:
Hooray, you opened the JavaScript console. Have fun!
var div = d3.selectAll("div").data(vowels, name);
(index):165 Uncaught TypeError: Cannot read property 'name' of undefined
at HTMLDivElement.name (https://bost.ocks.org/mike/selection/:165:11)
at e (https://d3js.org/d3.v3.min.js:3:13654)
at Array.Co.data (https://d3js.org/d3.v3.min.js:3:14326)
at <anonymous>:1:31name @ (index):165e @ d3.v3.min.js:3Co.data @ d3.v3.min.js:3(anonymous function) @ VM3012:1
(这是在Max OS X 10.11和Google Chrome上,但这应该是无关紧要的,因为问题不依赖于机器,如下所述。
对Data
(绑定)方法的误解
但这是真正让我感到困惑的事情:
- 据我了解,从此页面上的 Mike 自己的文档中,无论如何,这应该不起作用。
data
方法基本上创建 2 个层次结构级别:单个"组",然后是组下的一堆元素。- 因此,该方法创建 1 组和 5 个元素,元素包含数据。 然后,我们尝试在数据中查找属性,但在组级别,而不是元素级别。 我理解对吗?
但是,如果我们只是传递 - 数据,或者只是传递一个解释数据的函数,例如
d3.selectAll("div").data(d3.entries(letters))
,那么事情又可以正常工作。
所以似乎显然有两件事正在发生:
- 我自己对
data
方法如何工作或应该如何工作的这种微妙之处的误解。 - D3 本身中的一些更改,使得本教程无法再像以前那样运行。
这仍然全部使用 D3 的 V3,正如该页面本身的源代码所说:
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script></script>
我打算将其作为这个问题的副本关闭,但我认为它需要更多的解释。
简而言之,这是预期的行为。 您基本上具有现有的div,没有绑定任何数据。 键函数尝试在它们上执行,d
未定义,你会得到你的uncaught typerror
。 以下是简化版本:
var letters = [
{name: "A", frequency: .08167},
{name: "B", frequency: .01492},
{name: "C", frequency: .02780},
{name: "D", frequency: .04253},
{name: "E", frequency: .12702}
];
function name(d) {
return d.name;
}
d3.selectAll("div").data(letters, name);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
但是等等,这意味着教程被严重破坏了,对吧?
不,您看到这一点是因为您无序地执行它。 上一步让您在没有key
函数的情况下将数据绑定到这些div。 然后,当您与 key
函数重新绑定时,这些div 上有现有数据(d
已定义),您的问题就消失了:
var numbers = [4, 5, 18, 23, 42];
var letters = [
{name: "A", frequency: .08167},
{name: "B", frequency: .01492},
{name: "C", frequency: .02780},
{name: "D", frequency: .04253},
{name: "E", frequency: .12702}
];
function name(d) {
return d.name;
}
d3.selectAll("div").data(numbers);
d3.selectAll("div").data(letters, name);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
但是等等,这很糟糕,d3
不应该为我处理这个问题吗?
不,因为在现实生活中d3
使用中,你永远不会真正看到这一点。您不会有预先存在的<div>
来绑定数据。 相反,您将使用 d3
来管理这些<div>
的整个生命周期(完整的进入、退出、更新周期)。 简而言之,这些div 将始终是数据绑定的,否则您将永远不需要它们。
var letters = [
{name: "A", frequency: .08167},
{name: "B", frequency: .01492},
{name: "C", frequency: .02780},
{name: "D", frequency: .04253},
{name: "E", frequency: .12702}
];
function name(d) {
return d.name;
}
d3.select("body")
.selectAll("div")
.data(letters, name)
.enter()
.append("div")
.html(function(d){ return d.name });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
- 如何传递函数中的参数
- 如何在单击、Knockout时传递函数中的值
- D3选择html——传递函数时,索引从1开始,而不是从0开始
- 将数据从promise then方法传递到对象方法
- 尝试将变量传递到对象中时的作用域问题'的方法构造函数
- 对象方法中函数中的上下文
- 在谷歌地图的addListener事件中传递函数
- 如何在javascript中设置传递函数
- 什么's调用函数和传递函数的区别
- JavaScript 将循环遍历数组的函数传递给使用 Switch 语句日期方法的函数
- Javascript:如何使用apply方法传递参数数组,然后在被调用的函数中访问它
- 在Javascript中调用不带传递函数的组合私有类成员的公共实例方法
- 如何传递到该数组中对象的数组访问属性的排序方法的函数
- 是否有其他方法传递对象引用到javascript匿名函数
- 在使用选择器时传递函数参数的好方法是什么?
- 如何将方法传递给函数
- 正确使用 D3 “data” 方法,并传递函数和数据集
- 当将实例方法传递给另一个函数时,如何访问实例方法中的实例属性
- 如何通过方法传递类实例而不调用构造函数
- 如何在ios中从objective c方法传递javascript函数的元素id