gpt4 book ai didi

d3.js - D3JS : appending simple nested HTML in a single command

转载 作者:行者123 更新时间:2023-12-01 11:16:23 24 4
gpt4 key购买 nike

考虑这个简单的 HTML block :

<div id="somediv">
<btn id="somebutton">Abc</btn>
<div class="nested">
<span id="span1">Blah blah blah</span>
<span id="span2">Bleh bleh bleh</span>
</div>
</div>

我想使用 D3JS 动态地重新创建它。

这可以很好地用于此目的:

(function() {

var somediv = d3.select( 'body' ).append( 'div' ).attr( 'id', 'somediv' );

somediv.append( 'btn' )
.attr( 'id', 'somebutton' )
.html( 'Abc' );

var nested = somediv.append( 'div' )
.attr( 'class', 'nested' );

nested.append( 'span' ).attr( 'id', 'span1' ).html( 'Blah blah blah' );
nested.append( 'span' ).attr( 'id', 'span2' ).html( 'Bleh bleh bleh' );

})();

…然而,它非常冗长,有四个命令和两个临时变量…最重要的是,它不容易阅读——不喜欢它。

我正在寻找一种通过单个命令完成此操作的方法。

到目前为止,我有这个:

    d3.select( 'body' )
.append( 'div' )
.attr( 'id', 'somediv' )
.append( 'btn' )
.attr( 'id', 'somebutton' )
.html( 'Abc' )
.append( 'div' )
.attr( 'class', 'nested' )
.append( 'span' ).attr( 'id', 'span1' ).html( 'Blah blah blah' )
.append( 'span' ).attr( 'id', 'span2' ).html( 'Bleh bleh bleh' );

…然而(正如预期的那样),这会导致不断嵌套(即:span2 在 span1 中,在 div 中,在 btn 中,在 #somediv 中。)

D3 JS API 中有什么东西可以让我返回(到)父元素以继续从它追加吗?

最佳答案

您可以在单个命令中执行此操作,但它可能变得不如您拥有的多个命令可读。例如:

d3.select("body")
.append("div")
.each(function() {
d3.select(this).append("button").html("button")
d3.select(this).append("div")
.each(function() {
d3.select(this).append("span").text("span")
d3.select(this).append("span").text("span")
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

如您所见,这当然有效,但它可能不被认为是可读的,因为它是一种不寻常的 d3 模式,尤其是当您需要与熟悉 d3 的其他人共享代码时。随着我们进一步嵌套,可读性可能会降低。

您也可以使用我在之前的 answer 中建议的方法, 并创建一个 selection.appendSibling 方法。通过创建方法的额外冗长,您可以获得看起来更干净的东西:

// modify d3.selection so that we can append a sibling
d3.selection.prototype.appendSibling = function(type) {
var siblings = this.nodes().map(function(n) {
return n.parentNode.insertBefore(document.createElement(type), n.nextSibling);
})
return d3.selectAll(siblings).data(this.data());
}

d3.select("body")
.append("div")
.append("button").html("button")
.appendSibling("div") // append a sibling div to the button
.append("span").text("span1")
.appendSibling("span").text("span2"); // append a sibling span to the first span
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

但我不建议使用这种方法 - 不清楚每行操作的是什么选择。它旨在在处理成对元素时使用,例如 dldd 元素。


虽然以上两个有效,而且您还可以使用 enter 循环来附加两个跨度而不是独立的附加语句,但我仍然建议像您最初使用的那样将代码分成多个段:

var container = d3.select("body").append("div");

var button = container.append("button").html("button");

var spans = container.append("div")
.selectAll(null)
.data([1,2])
.enter()
.append("span")
.text(function(d) { return "span"+ d; })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

(当然,我们可以跳过 span 和 button 的 var 声明以使事情更紧凑)

或者,更符合前两个片段:

var container = d3.select("body").append("div");
var button = container.append("button").html("button");
var div = container.append("div");
var span1 = div.append("span").text("span1")
var span2 = div.append("span").text("span2");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

(同样,如果认为是噪音,我可以删除不必要的 var 声明)

最后两个片段实际上比第一个短。

虽然这偏离了问题,但我相信最后两个片段是有利的,原因有几个:

  • 它允许轻松操作独立元素 - 假设您想要按钮上的事件监听器,或者事后更改它
  • 很清楚正在操纵什么选择
  • 其他读者/同事更熟悉/更容易理解。

关于d3.js - D3JS : appending simple nested HTML in a single command,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50491651/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com