在 D3 中,我们可以将数据绑定到 DOM 中的 HTML 元素。类似于将数据(在JavaScript中定义)关联到元素,这些元素稍后可以被引用来执行操作。
绑定
要制作图形,还必须使用 data 和 attr 方法。
- data() 方法是D3的灵魂。通过它,一个数据数组被绑定到页面元素。
- attr() 方法允许我们设置页面元素的属性。在本例中,我们设置了height、width、color和x/y location属性。
<script src="https://d3js.org/d3.v6.min.js"></script>
<div id="view010601"></div>
<script>
data = [1, 2, 3, 4];
d3.select("#view010601") // select the view
.selectAll("p") // empty <p> selections to be used later
.data(data) // parses data, and runs below operations n times
.enter() // creates new data-bound element
.append("p") // append <p> tag for each datum
.text("I'm no. 1"); // changes attribute's value
</script>
用户自定义函数
<script src="https://d3js.org/d3.v6.min.js"></script>
<div id="view010602"></div>
<script>
data = [1, 2, 3, 4];
d3.select("#view010602")
.selectAll("p")
.data(data)
.enter()
.append("p")
.text(function(d) {return "I'm no " + d}) // custom function
</script>
奇偶判断?
<script src="https://d3js.org/d3.v6.min.js"></script>
<div id="view010603"></div>
<script>
data = [1, 2, 3, 4];
d3.select("#view010603")
.selectAll("p")
.data(data)
.enter()
.append("p")
.text(function(d) {return "I'm no " + d})
.style("color", function(d) {
if (d%2 == 0) { return "red" } // if even
})
</script>
匿名函数
在我们的代码示例中,我们将 x,y,height 设置为匿名函数。这些可能有点混乱,所以让我们深入了解一下这意味着什么。
传递给函数的参数 d 表示我们的数据集。匿名函数有一个参数,用于刚绑定到 data 语句中页面元素的数据值。这是 D3 内置的。此变量(d)的名称是任意的,但通常使用d,因为它表示数据值。
绑定到页面元素的数据本身就是一个对象。在这个例子中,d 是我们的对象,可以在这个函数中进行局部操作。如果我们的数据对象有属性,您可以在此步骤中引用这些属性。例如,如果我们的数据集是一个JSON,有两个属性,number of rats(number)和city(city),我们可以像在任何其他JavaScript对象中一样引用它。i、 e.d.号码。我们稍后会更详细地看这个!
<script src="https://d3js.org/d3.v6.min.js"></script>
<div id="view010604"></div>
<script>
// Width and height of the SVG object
w = 150;
h = 155;
data = [ 40, 90, 30, 60 ];
svg = d3.select('#view010604')
.append( "svg" );
svg.selectAll( "rect" )
.data( data )
.enter()
.append( "rect" )
.attr( "x", (d,i) => (i*25 + 30))
// Set x coordinate of rectangle to index of data value (i)*25.
// Add 30 to account for our left margin.
.attr( "y", d => h-d ) // Set y coordinate for each bar to height minus the data value
.attr( "width", 20 )
.attr( "height", d => d) // Set height of rectangle to data value
.attr( "fill", "steelblue");
</script>
我们所做的是选择一堆不存在的矩形,所以我们得到一个空的选择。上面代码块中接下来的几行代码通过绑定数据、使用 enter() 并附加新元素来创建这些元素。
- data() -我们使用 data()方法将数据绑定到空选择,它将返回数据集中的四个数据值。
- enter() -加载数据时,它将遍历数据集,并将所有方法应用于数据集的每个值。enter()方法为找不到相应DOM元素的每个数据元素创建占位符。因为它是迭代的,所以它将创建四个占位符。
- append() —最后,append(“rect”)方法将在每个没有“rect”元素的占位符中插入一个矩形,这是它们的全部。
- attr() —迭代设置属性,例如每个矩形元素的(x,y)位置、宽度和高度。现在,它们都位于相同的位置(0,0),具有相同的宽度(20)和高度(100)。我们需要使用函数使其正常工作,并将在下一步对此进行详细说明。
Enter 和 Exit 函数是如何工作的
enter() 和 exit() 方法分别基于传入数据处理新元素和未使用的元素。花一分钟的时间完全掌握这些是值得的!
enter() 方法告诉 D3 当数据数组中的元素多于选择中的元素时该怎么做。因此,如果在一个输入数据集中有12行,但在调用 enter() 方法时只有8个 rect 元素,那么 D3 将转到 enter() 方法后面的部分来确定要做什么。通常,enter 函数将用于为给定的可视化创建 append() 新元素。exit() 方法告诉 D3 当数据数组中的元素多于选择中的元素时该怎么做。通常,这将用于清除不再需要的元素。你可以把它们想象成'go'和'stop'方法,其中 enter() 是前者,exit() 是后者。
对于数据中的每个值,运算符都会以一对一的方式检查是否存在相应的 DOM 元素:
- enter 状态是一个选择,它包含每个数据值的占位符,这些数据值在原始选择中没有对应的元素。
- 更新状态是包含与绑定数据值匹配的现有元素的选择。
- 退出状态是一个也包含现有元素的选择,但找不到与其匹配的数据值时该如何处理。
匹配项由.data的第二个参数确定,该参数指定一个键函数。如果没有指定键函数(如上面的代码单元),D3 将执行索引连接:第一个数据值连接到第一个 DOM 元素,第二个值连接到第二个元素,依此类推。
课后作业
修改前面的代码,修改条形图的颜色,还有将条形图改变方向。