4

有没有一种简单的方法来扩展以下代码,以便div.someclass在它不存在时自动创建?

d3.select("body").select("div.someclass").selectAll("p")
    .data([ 1, 2, 3 ])
    .enter()
        .append("p")
        .text(function (d, i) {
            return "index: " + i + ", value: " + d;
        });

我仍处于学习 D3JS 的早期阶段。到目前为止,我对它的理解是“不要告诉 D3 如何做某事,而是告诉 D3 你想要什么”。所以我很惊讶地看到上面这段代码需要<div class="someclass"></div>在 HTML 中声明。

另一种方法是以编程方式插入 div:

/** Append HTML placeholder programmatically **/
placeholder = d3.select("body").append("div").attr("class", "someclass");

/** Bind the data to the DOM **/
/** instead of telling D3 how to do something, tell D3 what you want: in the absence of <p>, this will return a virtual selection **/
placeholder.selectAll("p")
    .data([ 1, 2, 3 ])
    .enter()
        .append("p")
        .text(function (d, i) {
            return "index: " + i + ", value: " + d;
        });

有没有更短/更好的方法?

4

2 回答 2

12

如果我理解正确,您是在问如何附加div.someClassIFF 它不存在。这有一个 D3 模式,虽然有点奇怪:

// create a selection for the container with a static 1-element array
var container = d3.select("body").selectAll("div.someclass")
    .data([0]); 

// now add it if it doesn't exist
container.enter().append('div').attr('class', 'someclass');

// now use it for the subselection
container.selectAll("p")
    .data([1, 2, 3]);

// etc

这里的奇怪部分是.data([0])- 这0是常规的,不是必需的;这可以是任何静态单元素数组。第一次调用时,将创建一个新元素(除非先创建其他元素div.someclass)。第二次,元素已经存在,所以没有.enter()选择,也不会添加更多内容。

这是可重用组件中相当常见的模式,旨在在更新时重复调用 - 请参阅d3.svg.axis代码以获取示例。

于 2013-10-31T21:36:11.870 回答
0

你这样做的方式是正确的。通常,您以编程方式将类添加到以编程方式创建的节点。例如,您正在创建新<p>元素,因此如果您想要一个类,那么是时候在那里添加一个类了:

placeholder.selectAll("p")
    .data([ 1, 2, 3 ])
    .enter()
    .append("p")
        .attr("class", "myclass")   <-- add class here
        .text(function (d, i) {
            return "index: " + i + ", value: " + d;
        });

对于您不使用 D3 管理其生命周期的元素,您还需要以其他方式管理这些元素的属性。这可以在初始 HTML 中进行硬编码,或者您可以完全按照自己的方式添加特殊处理。

或者,还有一个名为selection.classed的 API ,当且仅当它们不存在时才会添加或删除类。如果您的元素可能有许多类,并且您只想从列表中切换一个(而不是selection.attr("class", "myclass"),这将很方便,这将破坏整个属性。

于 2013-10-31T18:08:41.290 回答