Steekatsee
Steekatsee

Reputation: 319

D3.js, multiply element <g>

I'm D3.js newbie. I'm trying to duplicate an SVG group but I can't understand how to correctly do it. This is my group:

// external <g>
var group = svg.append("g");
group.attr("class", "myGroup");
group.append('circle')
.attr({cx:20,cy:100,r:4,fill:'black','fill-opacity':1,stroke:'red','stroke-width':0});

// inner <g> with line and text
var groupLine = group.append('g');
groupLine.append('line')
.attr({x1:20,y1:100,x2:20,y2:20,stroke:'black','stroke-width':0.4});
groupLine.append('text')
.text('texttext')
.attr({x:200,y:200,'text-anchor':'start','transform':'translate(-182,294) rotate(-90)'})
.style("font-family","Verdana")
.style("font-size","12px");

(fiddle here: http://jsfiddle.net/n7Qs3/)

Now, based on a simple array (D3.js, position elements horizontally), I want to multiply this group, creating 6 groups and position them horizontally. Basicly, the idea is the same as the ancient Flash duplicateMovieClip.

How can I do?

Upvotes: 1

Views: 668

Answers (2)

Ed Die
Ed Die

Reputation: 227

This is how I 'clone' multiple buttons.

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

    for (var i = 1; i < number_to_duplicate; i++) {
        d3.select("#some_other_id")
          .append("button")
          .attr("type","button")
          .attr("class","btn-btn")
          .attr("id",function(d) { return 'button '+i;})
          .append("div")
          .attr("class","label")
          .text(function(d) { return 'button '+i;})
    }
    };)

I create div and .each(function). Int the function the for loop creates the buttons.

For your purposes you would change the attributes including (x: x times i) for positioning. But anyway this is my very simple solution to make buttons or similar elements with different ids. Labels could be attached outside the loop.

So I guess you could do: create a div, attach .each, invoke a function in each containing the for loop, using i as multiplier for the position:

    .each(function(d) {

    for (var i = 1; i < number_to_duplicate; i++) {
     d3.select("#some_other_id")
       .append('line')
       .attr({x1:20*i,y1:100,x2:20*i,y2:20,stroke:'black','stroke-width':0.4});
       .text('texttext')
       .attr({x:200*i,y:200,'text anchor':'start','transform':'translate(-182,294) rotate(-90)'})
       .style("font-family","Verdana")
       .style("font-size","12px");
    }
    };)

Upvotes: 0

Lars Kotthoff
Lars Kotthoff

Reputation: 109232

There's nothing built into D3 for this, but you can use .cloneNode():

var newNode = group.node().cloneNode(true);
svg.append(function() { return newNode; });

The only thing you need to do is set the offset for each copy:

newNode.setAttribute("transform", "translate(" + (i * 100) + ",0)");

Complete demo here.

Upvotes: 2

Related Questions