如何在d3.js中的兄弟元素之后插入

Red*_*ant 6 javascript jquery charts svg d3.js

我想foreign object在人们放大圆圈时插入一个.我知道有一个Insert before:

function zoom(d, i) {
     d3.select("g").insert("foreignObject",'#'+d.name) // insert after a circle in the group
          .attr("width",450)
          .attr("height",450) 
          .attr("id",'f_'+d.name)
          .append("xhtml:div")
          .html(content)

}
Run Code Online (Sandbox Code Playgroud)

但是点击的圈子会使html内容变得模糊不清.有没有insert after a specific sibling这样的外部对象会在它之后插入?

不要打扰罗伯特·朗森的回答.他只是拿了他在文件中读到的东西而没有证明有效.

@代码:

var w = 1280,
    h = 800,
    r = 720,
    x = d3.scale.linear().range([0, r]),
    y = d3.scale.linear().range([0, r]),
    node,
    root;

var pack = d3.layout.pack()
    .size([r, r])
    .value(function(d) { return d.size; })

var vis = d3.select("body").insert("svg:svg", "h2")
    .attr("width", w)
    .attr("height", h)
  .append("svg:g")
    .attr("transform", "translate(" + (w - r) / 2 + "," + (h - r) / 2 + ")");

node = root = data;
  console.log(node)
  var nodes = pack.nodes(root);

  vis.selectAll("circle")
      .data(nodes)
    .enter().append("svg:circle")
      .attr("class", function(d) { return d.children ? "parent" : "child"; })
  .attr("id",function(d){ return d.name; })
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; })
      .attr("r", function(d) { return d.r; })
      .on("click", function(d) { return zoom(node == d ? root : d); });

  vis.selectAll("text")
      .data(nodes)
    .enter().append("svg:text")
      .attr("class", function(d) { return d.children ? "parent" : "child"; })
      .attr("x", function(d) { return d.x; })
      .attr("y", function(d) { return d.y; })
      .attr("dy", ".35em")
      .attr("text-anchor", "middle")
      .style("opacity", function(d) { return d.r > 20 ? 1 : 0; })
      .text(function(d) { return d.name; });

  d3.select(window).on("click", function() { zoom(root); });


function zoom(d, i) {
  console.log(d)
  var k = r / d.r / 2;
  x.domain([d.x - d.r, d.x + d.r]);
  y.domain([d.y - d.r, d.y + d.r]);

  var t = vis.transition()
      .duration(d3.event.altKey ? 7500 : 750);

  t.selectAll("circle")
      .attr("cx", function(d) { return x(d.x); })
      .attr("cy", function(d) { return y(d.y); })
      .attr("r", function(d) { return k * d.r; });

  t.selectAll("text")
      .attr("x", function(d) { return x(d.x); })
      .attr("y", function(d) { return y(d.y); })
      .style("opacity", function(d) { return k * d.r > 20 ? 1 : 0; });
  if(!d.children)
  {    
    if(!$('#f_'+d.name).length){ 
  d3.select("g").insert("foreignObject",'#'+d.name)
      .attr("width",450)
      .attr("height",450) 
      .attr("id",'f_'+d.name)
      .append("xhtml:div")
      .html('<img src="https://www.gravatar.com/avatar/60163c0083f4d2a54de2bb079a7211f8?s=128&d=identicon&r=PG&f=1">')
    }
  }
  else
  {
     $("foreignObject").attr("opacity",0); 

  }    
  node = d;
  d3.event.stopPropagation();
Run Code Online (Sandbox Code Playgroud)

Kre*_*zot 9

您可以使用css"element + element"选择器(直接相邻组合器).假设你需要在元素"first"之后插入元素"second":

d3.select('body')
    .insert('div', '#first + *')
    .attr('id', 'second');
Run Code Online (Sandbox Code Playgroud)

  • 我不认为这会在 `#first` 之后没有元素的情况下起作用,但它确实起作用,因为作为 [docs](https://github.com/d3/d3-3.x -api-reference/blob/master/Selections.md#insert) 解释一下,如果选择器不匹配任何元素,则将 `insert` 视为 `append`。所以是的,谢谢! (2认同)

Rob*_*son 3

您可以使用insert将内容插入到任何其他同级元素之前,现有同级元素是 insert 方法的第二个参数。

如果要在元素 x 之后插入,则需要创建一个选择器来立即返回 x 之后的元素。

如果您想在所有现有同级之后插入,请使用append

您可以在这两种方法之间的任何位置插入。