score:12

Accepted answer

You want selection.each() rather than selection.call(). Selection.call will will invoke a function just once, while .each will invoke it for each datum:

selection.each(function) <>

Invokes the specified function for each selected element, in order, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element (nodes[i]). This method can be used to invoke arbitrary code for each selected element...

Compare to:

selection.call(function[, arguments…]) <>

Invokes the specified function exactly once, passing in this selection along with any optional arguments.

(API Documentation (v4, but both methods exist in v3))

See the following snippet for a comparison of both:

var data = [10,20,30,40];

var selection = d3.select("body").selectAll(null)
  .data(data)
  .enter()
  .append("p")
  .each(function(d) {
    console.log("each: " + d); // d is datum
  })
  .call(function(d) {
    console.log("call: ") 
    console.log(d.data()); // d is selection
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

To call this function once on each item, you could use .call within the .each. I've used a g to place the text, so that the tspans this utility creates are positioned correctly (otherwise they overlap). The following snippet otherwise uses your code (the word wrap utility is on top as I could not find a cdn for it quickly enough):

d3.util = d3.util || {};

d3.util.wrap = function(_wrapW){ 
    return function(d, i){
        var that = this;

        function tspanify(){ 
            var lineH = this.node().getBBox().height;
            this.text('')
                .selectAll('tspan')
                .data(lineArray)
                .enter().append('tspan')
                .attr({
                    x: 0,
                    y: function(d, i){ return (i + 1) * lineH; } 
                })
                .text(function(d, i){ return d.join(' '); })
        }   

        function checkW(_text){ 
            var textTmp = that
                .style({visibility: 'hidden'})
                .text(_text);
            var textW = textTmp.node().getBBox().width;
            that.style({visibility: 'visible'}).text(text);
            return textW; 
        }

        var text = this.text();
        var parentNode = this.node().parentNode;
        var textSplitted = text.split(' ');
        var lineArray = [[]];
        var count = 0;
        textSplitted.forEach(function(d, i){ 
            if(checkW(lineArray[count].concat(d).join(' '), parentNode) >= _wrapW){
                count++;
                lineArray[count] = [];
            }
            lineArray[count].push(d)
        });

        this.call(tspanify)
    }
};

var wrap = d3.util.wrap(11);

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

var myData = ["text 1","text 2","text 3"]

var quote = svg.selectAll("text.quote").data(myData);
quote.enter().append("g")

quote.attr("class","quote")
.attr("transform", function (d,i){ return "translate(20," + (i * 40 + 20) + ")" })
.append("text")
.text(function(d, i){return d})
.each(function() {
  d3.select(this).call(d3.util.wrap(11));
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>


Related Query

More Query from same tag