D3选择和输入

时间:2014-08-07 22:35:03

标签: javascript html d3.js

我尝试使用d3.js创建元素,首先使用唯一标识符选择标记,在本例中为#34; mydat"。但是,以下代码并没有给我任何东西。

<body>
<div id="mydat"></div>
<script src="http://d3js.org/d3.v3.js"></script>
<script>
for (i=0; i<5; i++) {
d3.select("body").select("#mydat")
    .data(i.toString())
    .enter()
    .append("div")
    .text(String)
}
</script>
</body>

另一方面,如果我使用选择:

d3.select("body").select("div")

并删除第一个

<div id="mydat"></div>

然后我得到

<div>1</div><div>2</div>

等。我很困惑。为什么不是第一种选择方法,即

d3.select("body").select("#mydat")

识别现有的&#39; div&#39;标记并放置孩子&#39; div&#39;里面的标签?另外,如果我不删除现有的&#39; div id =&#34; mydat&#34;&#39 ;?,为什么第二种选择方法不起作用?感谢。

3 个答案:

答案 0 :(得分:2)

正确的做法是

var data = d3.range(0,5);

d3.select("body").select("#mydat")
    .selectAll("div")
    .data(data)
    .enter()
    .append("div")
    .text(function(d) { return d; })

您遇到的行为是代码中出现的两个错误的混合。

第一个问题是.data()应该接受一个数据数组,一个字符串可以被视为一个字符数组,所以d3将字符串分成几个字符。对于0 <= i < 5,这并不明显,但如果您将i更改为两位数,则会看到divs,如下所示:

<div>1</div> //10
<div>0</div>
<div>1</div> //11
<div>1</div>
<div>1</div> //12
<div>2</div>

修复方法是删除循环,然后传入一组数据。循环在d3中是罕见的,因为它具有许多强大的功能,可以同时对元素组进行操作。

第二个问题,以及您的选择未按预期工作的原因,与父元素有关。

  

然后将enter.select的实现专门化为节点   插入到组的父级中,替换占位符。这个   这就是为什么在数据之前调用selection.selectAll是至关重要的   join:它建立父节点以输入元素。

Source: Mike Bostock's explanation of selections

基本上,append会将元素插入到当前选择的父节点的元素中。由于当前选择从未使用selectAll设置父级,因此您将遇到父节点的奇怪行为。始终使用selectAll显式设置父节点。

答案 1 :(得分:1)

在这种情况下,您不需要使用d3循环。

尝试:

var data = d3.range(0,5);
var sel = d3.select("#mydat").selectAll("div.mydatItem").data(data);
sel.enter().append("div").attr("class", "mydatItem");
sel.text(function(d) { return d;};

这将创建:

<div id="mydat">
    <div class="mydatItem">0</div>
    <div class="mydatItem">1</div>
    <div class="mydatItem">2</div>
    <div class="mydatItem">3</div>
    <div class="mydatItem">4</div>
</div>

select仅选择一个元素,而selectall将选择所有匹配的元素。也就是说,select("div")将选择它找到的第一个div,selectAll("div")将选择每个div。

我不完全清楚为什么你得到你看到的输出,但是你的“.data()”调用应该传递一组数据。您通常将非数组项目作为“data([item])”传递。

答案 2 :(得分:-2)

请改为尝试:

d3.select('#mydat') 

而不是

   d3.select('body').select('#mydat')