我有一个对象的 javascript 数组,其中每个对象都有 .ui 属性,该属性包含一个现有 SVG 形状/各种元素(一个自包含的“g”元素,里面有其他元素)。
我想在 D3 中将这些对象排列为力图布局。因此,我不想让 d3 创建圆圈(或其他),而是想将我的一个 ui 对象分配给图形。
我创建了一个 simplified fiddle << HERE >>为了那个原因。预先存在并且应该是图形一部分的对象是 3 个彩色矩形。在这个例子中我没有做到这一点。 d3 append 命令只能用于构建形状/元素,但不能附加已构建的形状/元素。我试图这样做,但它不能在 D3 中工作:
node.append( function(d) { d.ui.node(); }) ...
...如前所述,这不会起作用,因为 d3 不附加元素。
var svgContainer = d3.select("#svgContainer");
// =============================================================
// creates the SVG elements to be used ( 3 colored rectangles )
// =============================================================
var element0a = svgContainer.append("g").attr("transform","translate(100,100)");
var element0b = element0a.append("rect").attr("x",0).attr("y",0).attr("width",20).attr("height",10).attr("fill","red");
var element1a = svgContainer.append("g").attr("transform","translate(100,200)");
var element1b = element1a.append("rect").attr("x",0).attr("y",0).attr("width",20).attr("height",10).attr("fill","green");
var element2a = svgContainer.append("g").attr("transform","translate(100,300)");
var element2b = element2a.append("rect").attr("x",0).attr("y",0).attr("width",20).attr("height",10).attr("fill","blue");
// =============================================================
// fills up an object array that contains details plus the UI attribute
// =============================================================
var nodeArray = new Array();
nodeArray[0] = { id : "000", label : "label 000", ui : element0a };
nodeArray[1] = { id : "001", label : "label 001", ui : element1a };
nodeArray[2] = { id : "002", label : "label 002", ui : element2a };
// not interested in dealing with the edge/link right now, just empty
var linkArray = new Array();
// =============================================================
// D3 force layout stuff
// =============================================================
var force = self.force = d3.layout.force()
.nodes(nodeArray)
.links(linkArray)
.gravity(.05)
.distance(80)
.charge(-100)
.size([600, 600])
.start();
var node = svgContainer.selectAll("g.node")
.data(nodeArray)
.enter().append("svg:g")
.attr("class", "node")
.call(force.drag);
// HERE (below) COMES THE ISSUE, where you see append("cicle") I want to append the nodeArray's ".ui" element.
node.append("circle") // <---
.attr("class", "node")
.attr("r",10)
.attr("fill","orange")
.call(force.drag);
force.on("tick", function() {
node.attr("transform", function(d) {return "translate(" + d.x + "," + d.y + ")";});
});
最佳答案
基于 Lars Kotfoff 的建议:
工作 fiddle here
如果要绘制图形的元素已经存在,只需跳过 enter() D3 阶段并根据元素的共同特征(类名)使用 select() 或 selectAll()例如 )。
这就是元素的创建方式(添加了一个特定的类以允许隔离选择):
var element0a = svgContainer.append("g").attr("class","node").attr("transform","translate(100,100)");
var element0b = element0a.append("rect").attr("x",0).attr("y",0).attr("width",20).attr("height",10).attr("fill","red");
这是替换 enter() 阶段的代码的一部分
var node = svgContainer.selectAll("g.node")
.data(nodeArray)
.call(force.drag);
这是被删除的内容
var node = svgContainer.selectAll("g.node")
.data(nodeArray)
.enter().append("svg:g")
.attr("class", "node")
.call(force.drag);
// HERE (below) COMES THE ISSUE, where you see append("cicle") I want to append the nodeArray's ".ui" element.
node.append("circle") // <---
.attr("class", "node")
.attr("r",10)
.attr("fill","orange")
.call(force.drag);
关于svg - 如何使用现有 SVG 元素作为节点的 D3 强制布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16096173/