2015-01-31 11 views
5

Voglio inserire uno foreign object quando le persone eseguono lo zoom su una cerchia. So che c'è un Insert before:Come inserire dopo un elemento di pari livello in d3.js

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) 

} 

ma il contenuto HTML sarebbe oscurata dal cerchio fatto clic. Esiste un insert after a specific sibling in modo che l'foreignObject venga inserito dopo di esso?

Non infastidire la risposta di Robert Longson. Ha appena preso qualcosa che ha letto nel documento senza provare che funziona.

@ Codice:

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(); 
+0

Perché non 'append'? – benjaminz

risposta

1

È possibile utilizzare insert per inserire il contenuto prima di qualsiasi altro elemento di pari livello, l'elemento di pari livello attuale è il secondo argomento al metodo di inserimento.

Se si desidera inserire dopo l'elemento x, sarà necessario creare un selettore che restituisca l'elemento immediatamente dopo x.

Se si desidera inserire dopo tutti i fratelli esistenti quindi utilizzare append.

Tra questi due metodi è possibile inserire ovunque.

+0

Usa il secondo argomento da inserire per selezionare l'elemento dopo quell'elemento fratello. –

7

È possibile utilizzare il selettore css "elemento + elemento" (direct adjacent combinator). Diciamo è necessario inserire elemento "secondo" a destra dopo elemento "prima":

d3.select('body') 
    .insert('div', '#first + *') 
    .attr('id', 'second'); 
+0

Non pensavo che questo avrebbe funzionato nel caso in cui non ci fosse alcun elemento dopo quello di "# first', ma funziona, perché come [docs] (https://github.com/d3/d3-3. x-api-reference/blob/master/Selections.md # insert) spiega, se il selettore non corrisponde ad alcun elemento il 'insert' è trattato come un' append'. Quindi sì, grazie! – artfulrobot