Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Svg D3:追加选择的重复项_Svg_D3.js - Fatal编程技术网

Svg D3:追加选择的重复项

Svg D3:追加选择的重复项,svg,d3.js,Svg,D3.js,我想创建一个javascript函数,它可以接受一般的D3选择,并将其副本附加到SVG对象 下面是一个最低限度的工作示例: <!DOCTYPE html> <meta charset="utf-8"> <body> <script src="http://d3js.org/d3.v3.min.js"></script> <script> svg = d3.select("body").append("svg")

我想创建一个javascript函数,它可以接受一般的D3选择,并将其副本附加到SVG对象

下面是一个最低限度的工作示例:

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

svg = d3.select("body").append("svg")
                         .attr("width", 300)
                         .attr("height", 300);

circle = svg.append("circle")
              .attr("cx", 100)
              .attr("cy", 100)
              .attr("r", 20)

function clone_selection(x, i) {
  for (j = 0; j < i; j++) {
    // Pseudo code:
    // svg.append(an exact copy of x, with all the attributes)
  }
}

clone_selection(circle, 5);
</script>

svg=d3。选择(“正文”)。追加(“svg”)
.attr(“宽度”,300)
.attr(“高度”,300);
circle=svg.append(“circle”)
.attr(“cx”,100)
.attr(“cy”,100)
.attr(“r”,20)
功能克隆_选择(x,i){
对于(j=0;j
迈克·博斯托克说这是不可能的,但那是很久以前的事了


有人对如何实现这一目标有什么新想法吗?请记住,在函数
clone\u selection
中,我们不知道x中的svg元素是什么。

感谢@nrabinowitz为我指出
元素

以下是带有工作解决方案的MWE:

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

svg = d3.select("body").append("svg")
             .attr("width", 300)
             .attr("height", 300);

circle = svg.append("circle")
          .attr("id", "circleToClone")
          .attr("cx", 100)
          .attr("cy", 100)
          .attr("r", 20)

function clone_selection(object, i) {
  for (j = 0; j < i; j++) {
    // Here's the solution:
    cloned_obj = svg.append("use")
                .attr("xlink:href","#" + object.attr("id"));
  }
}

clone_selection(circle, 5);
</script>

svg=d3。选择(“正文”)。追加(“svg”)
.attr(“宽度”,300)
.attr(“高度”,300);
circle=svg.append(“circle”)
.attr(“id”,“circleToClone”)
.attr(“cx”,100)
.attr(“cy”,100)
.attr(“r”,20)
功能克隆_选择(对象,i){
对于(j=0;j
还有一种可能性:做事要长远。这解决了使用
元素时无法单独设置
样式
变换
属性的问题

我很惊讶神奇的
d3js
库在本机上没有这样的功能,但下面是我的技巧:

function clone_d3_selection(selection, i) {
            // Assume the selection contains only one object, or just work
            // on the first object. 'i' is an index to add to the id of the
            // newly cloned DOM element.
    var attr = selection.node().attributes;
    var length = attr.length;
    var node_name = selection.property("nodeName");
    var parent = d3.select(selection.node().parentNode);
    var cloned = parent.append(node_name)
                 .attr("id", selection.attr("id") + i);
    for (var j = 0; j < length; j++) { // Iterate on attributes and skip on "id"
        if (attr[j].nodeName == "id") continue;
        cloned.attr(attr[j].name,attr[j].value);
    }
    return cloned;
}
功能克隆\u d3\u选择(选择,i){
//假设选择仅包含一个对象,或仅包含一个工作对象
//在第一个对象上,“i”是要添加到
//新克隆的DOM元素。
var attr=selection.node().attributes;
变量长度=属性长度;
var node_name=selection.property(“nodeName”);
var parent=d3.select(selection.node().parentNode);
var cloned=parent.append(节点名称)
.attr(“id”,selection.attr(“id”)+i);
对于(var j=0;j
此函数对d3的选择进行深度复制,并返回复制元素的选择:

function cloneSelection(appendTo, toCopy, times) {
  toCopy.each(function() {
    for (var i = 0; i < times; i++) {
        var clone = svg.node().appendChild(this.cloneNode(true));
        d3.select(clone).attr("class", "clone");
    }
  });
  return appendTo.selectAll('.clone');
}
函数克隆选择(附录、复制、时间){
toCopy.each(函数(){
对于(变量i=0;i<次;i++){
var clone=svg.node().appendChild(this.cloneNode(true));
d3.选择(克隆).attr(“类”、“克隆”);
}
});
返回appendTo.selectAll('.clone');
}
见演示

如果选择的toCopy包含多个元素,此函数也可以使用

但是请注意,它会复制所有内容,以及所有内部元素的类、ID和其他属性,如果您在其他地方直接引用内部元素,这可能会破坏您的代码。因此,请注意您的选择。有一个父母,这使克隆人与原始人区别开来,并在选择链中提到它将使你安全


一个合理的做法(如果你真的非常需要id的话)是只在你正在复制的内容的外部元素上设置id,你可以通过修改函数来轻松地更改它:
d3.select(clone).attr(“class”,“clone”).attr(“id”,“clone-”+i)
回答这个问题可能有点晚,但当我开发出自己的解决方案时,我发现了这个问题。这就是我创建副本的方式

    d3.select("#some_id")
      .append("div")
      .attr("class","some_other_id")
      .each(function(d) {

    for (var i = 1; i < number_duplicate; i++) {
        d3.select("#some_other_id")
          .append("button")
          .attr("type","button")
          .attr("class","btn-btn")
          .attr("id","id_here")
          .append("div")
          .attr("class","label")
          .text("text_here")


    }
});
d3.选择(“某个id”)
.附加(“div”)
.attr(“类”、“某些其他id”)
.每个功能(d){
对于(变量i=1;i
我在其上创建一个div do.each(),并在each函数中放入一个for循环。 这个数字会告诉我复制品的数量


变化是可能的,可能一秒钟就行了,等等。可能是穷人的版本——我不是职业选手。我想听听你的反馈。

四年零四个月后。。。我制作了这个D3插件。

您正在寻找类似的产品吗?您需要一个真正的克隆,还是元素可以工作?谢谢您的评论。不过,这两种方法都不适用于一般的D3选择。关于这一点还有更多的讨论,但我想Mike Bostock提到的selection.clone()方法还没有实现。@nrabinowitz我实际上想要一个对象的浅拷贝,而不是克隆。这使元素更合适,对吗?我大概可以做
svg.selectAll(“use”).data(someData.enter().append().attr(“xlink:href”,“myID”)
Hmm。。我刚刚对此进行了测试,结果表明此方法并不理想,因为您无法将
样式
转换
属性应用于
对象。这意味着您必须使用初始对象的真实副本。回到绘图板…嗯-我很确定您可以覆盖
use
元素上的属性,如
fill
cx
cy
,等等。我很惊讶你不能使用
transform
,但是你总是可以用
g
包装元素,并应用转换和样式。这应该是更好的答案:)非常感谢。就我所知,这也是更好的答案@LondonRob,由于无法覆盖fill、cx、cy等,我发现如果原始svg有以下任何一种