通常,当我在三维场景图中对事物建模时,我首先描述低层次的组件,然后将它们组合成越来越复杂的工件。例如,创建一个轮胎,然后创建一个轮毂,然后将它们组合在一起来定义一个车轮。然后拿起车轮,车身和引擎,制造出一辆汽车。最后,把车放在世界上。
然而,D3通常表示为分解(自上而下的建模)。因此,您可以创建一个表,然后定义其标题,然后定义其行,然后定义每行中的单元格。
这两种方法各有优缺点,不过在3D建模方面,我已经看到很多新手纠缠不清,试图用自上而下的方法来描述一个复杂的场景。在自己的空间中考虑低级组件要容易得多,然后如何将它们放置并添加到父结构中。
D3对此有很大的偏见,但我还是决定尝试一种组合建模方法。
简而言之,它似乎没有得到支持。为了具体说明我的意思,我尝试先创建一个表头组件(),然后再将表头附加到一个表元素中。我收到了一条错误消息:
Uncaught InvalidCharacterError: Failed to execute 'createElement' on 'Document': The tag name provided ('[object HTMLDivElement]') is not a valid name.
我把它分解成一个非常简单的例子,它仍然会崩溃。
var component = document.createElement("div");
var d3component = d3.select(component).text("XYZZY");
var root = d3.select('#target');
// root.append(d3component); // FAILURE
root.append('div').text("FROTZ");<!DOCTYPE html> <html lang="en">
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<div id="target"></div>
</body>
</html>
如果将root.append(d3component)行注释掉,它将成功运行。但是,如果取消注释,则D3将失败,其中包含上述错误消息。
我是在这里遗漏了什么,还是D3真的不支持这种方法?
发布于 2016-06-17 00:46:02
在考虑了这个问题之后,我对我最初的答案感到不满意,我将在这篇文章的末尾保留这个问题,因为它是正确的,但它不知怎么地回避了“D3支持一种组合(自下而上)的方法吗?”答案应该是肯定的,但不是真的。
.append()或.insert()时隐式创建的。唯一的例外是为这些方法提供一个函数,它返回使用D3以外的方法创建的DOM元素。重要的是要理解,这不是一个缺陷,而是故意的。d3.select(document) ),并以自顶向下的方式添加或删除。长话短说,使用D3来模拟自下而上的方法是可能的,尽管它不是这样设计的。如果您决定尝试一下,请记住,它既不是最优雅的方式,也不是最直观的方法,而且可能会引入一些开销。要以自下而上的方式组合布局,可能值得评估其他更适合这种情况的库。
原始答案
不能使用.append()将D3的选择之一添加到DOM中。但是,您可以向.append()提供一个要追加的返回DOM元素函数。这可以通过将错误行替换为
root.append(function() { return component; });或者,如果您没有对元素的直接引用,则可以从所选内容中检索它。
root.append(function() { return d3component.node(); });然后,您的示例可能会如下所示
var component = document.createElement("div");
var d3component = d3.select(component).text("XYZZY");
var root = d3.select('#target');
root.append(function() { return component; });
// ...or...
//root.append(function() { return d3component.node(); });<!DOCTYPE html> <html lang="en">
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<div id="target"></div>
</body>
</html>
发布于 2016-06-17 00:42:34
使用正常的DOM选择可能会更好,但是使用d3是可能的:
var component = document.createElementNS("http://www.w3.org/1999/xhtml","div"); // note use of createElementNS
d3.select(component).text("XYZZY");
var root = d3.select('#target');
root[0][0].appendChild(component);
root.append('div').text("FROTZ");<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="target"></div>
https://stackoverflow.com/questions/37871270
复制相似问题