D3,嵌套的追加和数据流 [英] D3, nested appends, and data flow

查看:130
本文介绍了D3,嵌套的追加和数据流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在最后学习D3的过程中,我偶然发现了一个我还没有找到答案的问题。我不确定我的问题是否是因为我不习惯用图书馆,或者如果它是因为一个程序,我目前不知道。我还应该提到,我只是在6月开始做网络相关的事情,所以我是相当新的javascript。

I'm in the process of finally learning D3, and I stumbled upon a problem that I haven't been able to find an answer to. I'm not certain if my question is because I'm not thinking idiomatically with the library, or if it is because of a procedure that I am currently unaware of. I should also mention that I've only started doing web-related things in June, so I'm fairly new to javascript.

说我们正在建立一个工具其给予用户具有相应图像的食物的列表。并且添加额外的约束,每个列表项目需要标记一个唯一的ID,以便它可以链接到另一个视图。我的第一个直觉来解决这个问题是创建一个< div> 的列表,每个都有自己的ID,其中每个 div 有自己的< p> < img> 。生成的HTML看起来像:

Say that we're building a tool that gives a user a list of foods with respective images. And lets add on the additional constraint that each list item needs to be labeled by a unique ID so that it can be linked to another view. My first intuition to solve this is to create a list of <div>'s each with their own ID, where each div has its own <p> and <img>. The resulting HTML would look something like:

<div id="chocolate">
  <p>Chocolate Cookie</p>
  <img src="chocolate.jpg" />
</div>
<div id="sugar">
  <p>Sugar Cookie</p>
  <img src="sugar.jpg" />
</div>

此工具的数据位于JSON数组中,单个JSON如下所示:

The data for this tool is in a JSON array, where an individual JSON looks like:

{ "label": "sugar", "text": "Sugar Cookie", "img": "sugar.jpg" }

有没有办法一次生成HTML?从添加div的基本案例开始,代码可能如下所示:

Is there a way to do generate the HTML in one fell swoop? Starting with a base case of adding a div, the code might look something like:

d3.select(containerId).selectAll('div')                                                          
   .data(food)
   .enter().append('div')
   .attr('id', function(d) { return d.label; });

现在,添加< div> < p> ?我原来的想法是做一些像:

Now, what about adding a <div> with a <p> in it? My original thought was to do something like:

d3.select(containerId).selectAll('div')                                                          
   .data(food)
   .enter().append('div')
   .attr('id', function(d) { return d.label; })
       .append('p').text('somethingHere');

但是,我看到两个问题:(1) code> div 元素,以及(2)如何在一个声明链中将多个子元素附加到同一父元素?我不能想出一个方法来做第三步,我将附加在 img

But, I see two problems with this: (1) how do you get the data from the div element, and (2) how can you append multiple children to the same parent in one declarative chain? I can't think of a way to make the third step where I would append on the img.

I发现提及了另一篇文章的嵌套选择,指向 http://bost.ocks.org/mike/ nest / 。但是是嵌套的选择,因此分裂附加到三个块,适当/惯用的这种情况?或者,实际上有一个很好的方式来形成这个结构在一个链的声明?似乎可能有一种方法,在 https://github.com/mbostock/d3上提到的子选择/ wiki / Selections ,但我不熟悉这种语言来测试这个假设。

I found mention of nested selection on another post, which pointed to http://bost.ocks.org/mike/nest/. But is nested selection, and therefore breaking apart the appends into three chunks, appropriate/idiomatic for this situation? Or is there actually a well-constructed way to form this structure in one chain of declarations? It seems like there might be a way with subselections mentioned on https://github.com/mbostock/d3/wiki/Selections, but I'm not familiar enough with the language to test that hypothesis.

从概念层面来说,这三个对象c $ c> div , p img

From a conceptual level, these three objects (div, p, and img) are treated more like one group rather than separate entities, and it would be nice if the code reflected that as well.

推荐答案

您不能在其中添加多个子元素一个命令。您将需要将父选择保存在变量中。这应该做你想要的:

You cannot add multiple child elements within one chained command. You will need to save the parent selection in a variable. This should do what you want:

var data = [{ "label": "chocolate", "text": "Chocolate Cookie", "img": "chocolate.jpg" },
        { "label": "sugar", "text": "Sugar Cookie", "img": "sugar.jpg" }];

var diventer = d3.select("body").selectAll("div")
    .data(data)
  .enter().append("div")
    .attr("id", function(d) { return d.label; });

diventer.append("p")
    .text(function(d) { return d.text; });

diventer.append("img")
    .attr("src", function(d) { return d.img; });​

查看工作小提琴: http://jsfiddle.net/UNjuP /

您想知道像 p img 可访问绑定到其父级的数据。当您追加新元素时,系统会自动从父项继承数据。这意味着p和img元素将具有与父div相同的数据绑定。

You were wondering how a child element like p or img, gets access to the data that is bound to its parent. The data is inherited automatically from the parent when you append a new element. This means that the p and img elements will have the same data bound to them as the parent div.

此数据传播对于 append 方法。它会发生在以下选择方法中: append insert 选择

This data propagation is not unique for the append method. It happens with the following selection methods: append, insert, and select.

例如,对于selection.append:

For example, for selection.append:


< h1> selection.append(name)

将指定名称的新元素作为
的最后一个子元素添加到当前选择中的每个元素。返回包含所附元素的新选择
。每个新元素以与为
子选择选择相同的方式继承当前元素的数据
(如果有的话)。该名称必须指定为一个常量,但在
的未来,我们可能允许添加现有的元素或函数到
动态生成名称。

selection.append(name)

Appends a new element with the specified name as the last child of each element in the current selection. Returns a new selection containing the appended elements. Each new element inherits the data of the current elements, if any, in the same manner as select for subselections. The name must be specified as a constant, though in the future we might allow appending of existing elements or a function to generate the name dynamically.

如果不清楚,请随时询问详情。

Feel free to ask about the details if something is not clear.

您可以使用 selection.each 方法添加多个子元素,而不将选择存储在变量中。然后您也可以直接从父级访问数据:

You can add multiple child elements without storing the selection in a variable by using the selection.each method. You can then also directly access the data from the parent:

var data = [{ "label": "chocolate", "text": "Chocolate Cookie", "img": "chocolate.jpg" },
        { "label": "sugar", "text": "Sugar Cookie", "img": "sugar.jpg" }];

d3.select("body").selectAll("div")
    .data(data)
  .enter().append("div")
    .attr("id", function(d) { return d.label; })
    .each(function(d) {
        d3.select(this).append("p")
          .text(d.text);
        d3.select(this).append("img")
          .attr("src", d.img);
    });

这篇关于D3,嵌套的追加和数据流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆